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 handle_next_mail(self): """ parse the subject/content of a mail and take appropriate action. """ #blocking wait on sender_queue next_send_msg = self.queues["sender"].get(True) task_nr = str(next_send_msg.get('task_nr')) message_id = str(next_send_msg.get('message_id')) user_id = str(next_send_msg.get('user_id')) recipient = str(next_send_msg.get('recipient')) message_type = str(next_send_msg.get('message_type')) curs, cons = c.connect_to_db(self.dbs["semester"], self.queues["logger"], \ self.name) curc, conc = c.connect_to_db(self.dbs["course"], self.queues["logger"], \ self.name) attachments = [] # prepare fields for the e-mail msg = MIMEMultipart() msg['From'] = self.smtp_info["mail"] msg['To'] = recipient logmsg = "RECIPIENT: " + recipient c.log_a_msg(self.queues["logger"], self.name, logmsg, "DEBUG") msg['Date'] = formatdate(localtime=True) if message_type == "Task": ################# # TASK # ################# logmsg = "Task in send_queue: " + str(next_send_msg) c.log_a_msg(self.queues["logger"], self.name, logmsg, "DEBUG") # 2 Cases: # allow_requests == "once" or "multiple" -> send Task anyway # allow_requests == "no" : check if he is at a higher task_nr, # if yes: do not send cur_task = c.user_get_current_task(self.dbs["semester"], user_id, \ self.queues["logger"], self.name) at_higher_task = (cur_task > int(task_nr)) should_not_send = (self.allow_requests == "no") and at_higher_task if should_not_send: logmsg = ("Task sending initiated, but user already reveived " "this task!!!") c.log_a_msg(self.queues["logger"], self.name, logmsg, "ERROR") return data = {'task_nr': str(task_nr)} sql_cmd = ("SELECT TaskName FROM TaskConfiguration " "WHERE TaskNr == :task_nr") curc.execute(sql_cmd, data) res = curc.fetchone() if not res: logmsg = ("Failed to fetch Configuration for TaskNr: " "{0} from the database! Table " "TaskConfiguration corrupted?").format(task_nr) c.log_a_msg(self.queues["logger"], self.name, logmsg, "ERROR") message_text = ("Sorry, but something went wrong... " "probably misconfiguration or missing" "configuration of Task {0}").format(task_nr) msg = self.assemble_email(msg, message_text, '') self.send_out_email(recipient, msg.as_string(), \ message_type) self.archive_message(message_id) return task_name = res[0] description_path = self.course_info['tasks_dir'] + \ '/' + task_name + '/description.txt' if not os.path.isfile(description_path): logmsg = "No description.txt found for Task {0}.".format( task_nr) c.log_a_msg(self.queues["logger"], self.name, \ logmsg, "ERROR") message_text = ("Sorry, but something went wrong... " "probably misconfiguration or missing" "configuration of Task {0}").format(task_nr) msg = self.assemble_email(msg, message_text, '') self.send_out_email(recipient, msg.as_string(), message_type) self.archive_message(message_id) return msg['Subject'] = "Description Task" + str(task_nr) task_deadline = c.get_task_deadline(self.dbs["course"], task_nr, self.queues["logger"], self.name) dl_text = "\nDeadline for this Task: {0}\n".format(task_deadline) message_text = self.read_text_file(description_path) \ + dl_text data = {'task_nr': str(task_nr), 'user_id': user_id} sql_cmd = ("SELECT TaskAttachments FROM UserTasks " "WHERE TaskNr == :task_nr AND UserId == :user_id") curs.execute(sql_cmd, data) res = curs.fetchone() logmsg = "got the following attachments: " + str(res) c.log_a_msg(self.queues["logger"], self.name, logmsg, \ "DEBUG") if res: attachments = str(res[0]).split() else: attachments = "" msg = self.assemble_email(msg, message_text, attachments) self.send_out_email(recipient, msg.as_string(), message_type) self.archive_message(message_id) # Everything went okay -> adjust cur_task_nr c.user_set_current_task(self.dbs["semester"], task_nr, user_id, \ self.queues["logger"], self.name) elif message_type == "Failed": ################# # FAILED # ################# # did user already solve this task? data = {"user_id": user_id, "task_nr": task_nr} sql_cmd = ("SELECT UserId FROM UserTasks WHERE UserId = :user_id " "AND TaskNr = :task_nr AND FirstSuccessful IS NOT NULL") curs.execute(sql_cmd, data) res = curs.fetchone() task_already_solved = (res != None) #only update stat if user did not solve this task if not task_already_solved: self.increment_db_taskcounter('NrSubmissions', task_nr) path_to_msg = "users/{0}/Task{1}".format(user_id, task_nr) error_msg = self.read_text_file( "{0}/error_msg".format(path_to_msg)) msg['Subject'] = "Failure Task" + task_nr message_text = "Error report:\n\n" "" + error_msg reply_attachments = [] try: logmsg = "searching attachments in: {0}/error_attachments".format( path_to_msg) c.log_a_msg(self.queues["logger"], self.name, logmsg, "DEBUG") ats = os.listdir("{0}/error_attachments".format(path_to_msg)) logmsg = "got the following attachments: {0}".format(ats) c.log_a_msg(self.queues["logger"], self.name, logmsg, "DEBUG") for next_attachment in ats: reply_attachments.append( "{0}/error_attachments/{1}".format( path_to_msg, next_attachment)) except: logmsg = "no attachments for failed task." c.log_a_msg(self.queues["logger"], self.name, logmsg, "DEBUG") msg = self.assemble_email(msg, message_text, reply_attachments) self.send_out_email(recipient, msg.as_string(), message_type) # archive and notify that worker finished self.archive_message(message_id, is_finished_job=True) elif message_type == "Success": ################# # SUCCESS # ################# msg['Subject'] = "Success Task " + task_nr message_text = "You solved the task successfully. Congratulations!" msg = self.assemble_email(msg, message_text, '') self.send_out_email(recipient, msg.as_string(), message_type) #set first done if not set yet self.check_and_set_first_successful(user_id, task_nr) # last done had to be set now? --> Send Congrats if self.check_and_set_last_done(user_id): #new message, prepare it msg = MIMEMultipart() msg['From'] = self.smtp_info["mail"] msg['To'] = recipient logmsg = "RECIPIENT: " + recipient c.log_a_msg(self.queues["logger"], self.name, logmsg, "DEBUG") msg['Date'] = formatdate(localtime=True) message_text = self.read_specialmessage('CONGRATS') msg['Subject'] = "Congratulations on solving all Tasks!" msg = self.assemble_email(msg, message_text, '') self.send_out_email(recipient, msg.as_string(), "LastSolved") # archive and notify that worker finished self.archive_message(message_id, is_finished_job=True) elif message_type == "SecAlert": ################# # SEC ALERT # ################# admin_mails = self.get_admin_emails() for admin_mail in admin_mails: msg['To'] = admin_mail path_to_msg = "users/" + user_id + "/Task" + task_nr + "/error_msg" error_msg = self.read_text_file(path_to_msg) msg['Subject'] = "Security Alert User:"******"Error report:\n\n" "" + error_msg msg = self.assemble_email(msg, message_text, '') self.send_out_email(admin_mail, msg.as_string(), message_type) elif message_type == "TaskAlert": ################# # TASK ALERT # ################# admin_mails = self.get_admin_emails() for admin_mail in admin_mails: msg['To'] = admin_mail msg['Subject'] = "Task Error Alert Task{0} User{1}".format( \ str(task_nr), str(user_id)) message_text = ("There was an error with the Task {0} " \ "and User {1}. Check the logfiles(tasks.stderr, tasks.stdout, " "autosub.log) to find what caused it.").format(task_nr, user_id) msg = self.assemble_email(msg, message_text, '') self.send_out_email(admin_mail, msg.as_string(), message_type) elif message_type == "TaskErrorNotice": #################### # TASKERROR NOTICE # #################### admins = ",".join(self.get_admin_emails()) msg['Subject'] = "Error processing your last message" message_text = ( "There was an error processing your last message, please write an " "email to the administrators {0} and tell them about the time and what you did last. " "They will work on resolving the issue as soon as possible." ).format(admins) msg = self.assemble_email(msg, message_text, '') self.send_out_email(recipient, msg.as_string(), message_type) # archive, is_finished_job=True for tester errors, so the job can be # deleted from the active jobs # in the case this error is from a generator, the is_finished will be # ignored as the message_id will not be in the active jobs (see # fetcher.py) self.archive_message(message_id, is_finished_job=True) elif message_type == "Status": ################# # STATUS # ################# msg['Subject'] = "Your current status" message_text = self.generate_status_update(user_id, recipient, \ task_nr) numtasks = c.get_num_tasks(self.dbs["course"], self.queues["logger"], \ self.name) if int(numtasks) >= int(task_nr): #also attach current task data = {'task_nr': str(task_nr), 'user_id': user_id} sql_cmd = ("SELECT TaskAttachments FROM UserTasks " "WHERE TaskNr == :task_nr AND UserId == :user_id") curs.execute(sql_cmd, data) res = curs.fetchone() logmsg = "got the following attachments: " + str(res) c.log_a_msg(self.queues["logger"], self.name, logmsg, "DEBUG") if res: attachments = str(res[0]).split() msg = self.assemble_email(msg, message_text, attachments) self.send_out_email(recipient, msg.as_string(), message_type) self.archive_message(message_id) else: msg = self.assemble_email(msg, message_text, attachments) self.send_out_email(recipient, msg.as_string(), message_type) self.archive_message(message_id) elif message_type == "TasksList": ################# # TASKSLIST # ################# msg['Subject'] = "List of tasks" message_text = self.generate_tasks_list() msg = self.assemble_email(msg, message_text, attachments) self.send_out_email(recipient, msg.as_string(), message_type) self.archive_message(message_id) elif message_type == "InvalidTask": ################# # INVALID TASK # ################# msg['Subject'] = "Invalid Task Number" message_text = self.read_specialmessage('INVALID') msg = self.assemble_email(msg, message_text, '') self.send_out_email(recipient, msg.as_string(), message_type) self.archive_message(message_id) elif message_type == "TaskNotSubmittable": ######################### # TASK NOT SUBMITTABLE # ######################### msg['Subject'] = "Submission for Task{0} not possible".format( str(task_nr)) message_text = self.read_specialmessage('TASKNOTSUBMITTABLE') msg = self.assemble_email(msg, message_text, '') self.send_out_email(recipient, msg.as_string(), message_type) self.archive_message(message_id) elif message_type == "TaskNotActive": ######################### # TASK NOT ACTIVE # ######################### msg['Subject'] = "Task{0} not active yet".format(str(task_nr)) message_text = self.read_specialmessage('TASKNOTACTIVE') msg = self.assemble_email(msg, message_text, '') self.send_out_email(recipient, msg.as_string(), message_type) self.archive_message(message_id) elif message_type == "NoMultipleRequest": ######################### # NO MULTIPLE REQUEST # ######################### msg['Subject'] = "Already received Task{0}".format(str(task_nr)) message_text = self.read_specialmessage('NOMULTIPLEREQUEST') msg = self.assemble_email(msg, message_text, '') self.send_out_email(recipient, msg.as_string(), message_type) self.archive_message(message_id) elif message_type == "CurLast": ################# # CUR LAST # ################# # we still need to increment the users task counter! c.user_set_current_task(self.dbs["semester"], task_nr, user_id, \ self.queues["logger"], self.name) msg['Subject'] = "Task{0} is not available yet".format( str(task_nr)) message_text = self.read_specialmessage('CURLAST') message_text = "{0}\n\nThe Task is currently scheduled for: {1}".format(message_text, \ c.get_task_starttime(self.dbs["course"], str(task_nr), \ self.queues["logger"], self.name)) msg = self.assemble_email(msg, message_text, '') self.send_out_email(recipient, msg.as_string(), message_type) self.archive_message(message_id) elif message_type == "DeadTask": ################# # DEAD TASK # ################# msg['Subject'] = "Deadline for Task{0} has passed.".format( str(task_nr)) message_text = self.read_specialmessage('DEADTASK') msg = self.assemble_email(msg, message_text, '') self.send_out_email(recipient, msg.as_string(), message_type) self.archive_message(message_id) elif message_type == "Usage": ################# # USAGE # ################# msg['Subject'] = "Usage" message_text = self.read_specialmessage('USAGE') msg = self.assemble_email(msg, message_text, '') self.send_out_email(recipient, msg.as_string(), message_type) self.archive_message(message_id) elif message_type == "Question": ################# # QUESTION # ################# msg['Subject'] = "Question received" message_text = self.read_specialmessage('QUESTION') msg = self.assemble_email(msg, message_text, '') self.send_out_email(recipient, msg.as_string(), message_type) elif message_type == "QFwd": ################# # QFWD # ################# orig_mail = next_send_msg.get('body') orig_from = orig_mail['from'] orig_mail.replace_header("From", self.smtp_info["mail"]) orig_mail.replace_header("To", recipient) if task_nr: orig_mail.replace_header( "Subject", "Question Task" + task_nr + " from " + orig_from) else: orig_mail.replace_header("Subject", "Question from " + orig_from) self.send_out_email(recipient, orig_mail.as_string(), message_type) self.archive_message(message_id) elif message_type == "Welcome": ################# # WELCOME # ################# msg['Subject'] = "Welcome!" message_text = self.read_specialmessage('WELCOME') msg = self.assemble_email(msg, message_text, '') self.send_out_email(recipient, msg.as_string(), message_type) self.archive_message(message_id) elif message_type == "RegOver": ################# # REGOVER # ################# msg['Subject'] = "Registration Deadline has passed" message_text = self.read_specialmessage('REGOVER') msg = self.assemble_email(msg, message_text, '') self.send_out_email(recipient, msg.as_string(), message_type) self.archive_message(message_id) elif message_type == "NotAllowed": ################# # NOT ALLOWED # ################# msg['Subject'] = "Registration not successful." message_text = self.read_specialmessage('NOTALLOWED') message_text = message_text.replace("[[recipient]]", recipient) msg = self.assemble_email(msg, message_text, '') self.send_out_email(recipient, msg.as_string(), message_type) self.archive_message(message_id) elif message_type == "DeletedFromWhitelist": ############################ # DELETED FROM WHITELIST # ############################ msg['Subject'] = "Not whitelisted anymore" message_text = self.read_specialmessage('DeletedFromWhitelist') msg = self.assemble_email(msg, message_text, '') self.send_out_email(recipient, msg.as_string(), message_type) self.archive_message(message_id) else: ################# # UNKNOWN # ################# c.log_a_msg(self.queues["logger"], self.name, \ "Unkown Message Type in the sender_queue!", "ERROR") msg = self.assemble_email(msg, message_text, '') self.send_out_email(recipient, msg.as_string(), message_type) self.archive_message(message_id) cons.close() conc.close()
def handle_next_mail(self): """ parse the subject/content of a mail and take appropriate action. """ #blocking wait on sender_queue next_send_msg = self.sender_queue.get(True) task_nr = str(next_send_msg.get('Task')) messageid = str(next_send_msg.get('MessageId')) user_id = str(next_send_msg.get('UserId')) recipient = str(next_send_msg.get('recipient')) message_type = str(next_send_msg.get('message_type')) curs, cons = c.connect_to_db(self.semesterdb, self.logger_queue, \ self.name) curc, conc = c.connect_to_db(self.coursedb, self.logger_queue, \ self.name) attachments = [] # prepare fields for the e-mail msg = MIMEMultipart() msg['From'] = self.smtp_mail msg['To'] = recipient logmsg = "RECIPIENT: " + recipient c.log_a_msg(self.logger_queue, self.name, logmsg, "DEBUG") msg['Date'] = formatdate(localtime=True) if message_type == "Task": ################# # TASK # ################# logmsg = "Task in send_queue: " + str(next_send_msg) c.log_a_msg(self.logger_queue, self.name, logmsg, "DEBUG") numtasks = c.get_num_tasks(self.coursedb, \ self.logger_queue, self.name) cur_task_nr = c.user_get_current_task(self.semesterdb, user_id, \ self.logger_queue, self.name) ########################### NEEDED? ######################### # did user solve this task already? data = {"user_id": user_id, "task_nr": task_nr} sql_cmd = ("SELECT UserId FROM UserTasks WHERE UserId = :user_id " "AND TaskNr = :task_nr AND FirstSuccessful IS NOT NULL") curs.execute(sql_cmd, data) res = curs.fetchone() task_already_solved = (res != None) #did the user solve the previous task? data = {"user_id": user_id, "task_nr": int(task_nr) - 1} sql_cmd = ("SELECT UserId FROM UserTasks WHERE UserId = :user_id " "AND TaskNr = :task_nr AND FirstSuccessful IS NOT NULL") curs.execute(sql_cmd, data) res = curs.fetchone() prev_task_already_solved = (res != None) ############################################################# # user did not solve the task with highest TaskNr if numtasks + 1 != int(task_nr): # only send the task description, when the user just now got # to this task or it is the first task if int(task_nr) - 1 <= int(cur_task_nr) or int( cur_task_nr) == 1: msg['Subject'] = "Description Task" + str(task_nr) dl_text = "\nDeadline for this Task: {0}\n".format( c.get_task_deadline(self.coursedb, task_nr, self.logger_queue, self.name)) data = {'task_nr': str(task_nr)} sql_cmd = "SELECT PathToTask FROM TaskConfiguration WHERE TaskNr == :task_nr;" curc.execute(sql_cmd, data) paths = curc.fetchone() if not paths: logmsg = "It seems, the Path to Task {0} is not configured.".format( task_nr) c.log_a_msg(self.logger_queue, self.name, \ logmsg, "WARNING") message_text = "Sorry, but something went wrong... probably misconfiguration or missing configuration of Task {0}".format( task_nr) msg = self.assemble_email(msg, message_text, '') self.send_out_email(recipient, msg.as_string(), \ message_type) self.backup_message(messageid) else: path_to_task = str(paths[0]) path_to_msg = path_to_task + "/description.txt" message_text = self.read_text_file(path_to_msg) \ + dl_text data = {'task_nr': str(task_nr), 'user_id': user_id} sql_cmd = "SELECT TaskAttachments FROM UserTasks WHERE TaskNr == :task_nr AND UserId == :user_id;" curs.execute(sql_cmd, data) res = curs.fetchone() logmsg = "got the following attachments: " + str(res) c.log_a_msg(self.logger_queue, self.name, logmsg, \ "DEBUG") if res: attachments = str(res[0]).split() msg = self.assemble_email(msg, message_text, \ attachments) self.send_out_email(recipient, msg.as_string(), \ message_type) self.backup_message(messageid) #advance user's current TaskNr to the Task task_nr if he is not # at a higher task yet if int(cur_task_nr) < int(task_nr): c.user_set_current_task(self.semesterdb, task_nr, user_id, \ self.logger_queue, self.name) elif message_type == "Failed": ################# # FAILED # ################# # did user already solve this task? data = {"user_id": user_id, "task_nr": task_nr} sql_cmd = ("SELECT UserId FROM UserTasks WHERE UserId = :user_id " "AND TaskNr = :task_nr AND FirstSuccessful IS NOT NULL") curs.execute(sql_cmd, data) res = curs.fetchone() task_already_solved = (res != None) #only update stat if user did not solve this task if not task_already_solved: self.increment_db_taskcounter('NrSubmissions', task_nr) path_to_msg = "users/{0}/Task{1}".format(user_id, task_nr) error_msg = self.read_text_file( "{0}/error_msg".format(path_to_msg)) msg['Subject'] = "Task" + task_nr + ": submission rejected" message_text = "Error report:\n\n" "" + error_msg reply_attachments = [] try: logmsg = "searching attachments in: {0}/error_attachments".format( path_to_msg) c.log_a_msg(self.logger_queue, self.name, logmsg, "DEBUG") ats = os.listdir("{0}/error_attachments".format(path_to_msg)) logmsg = "got the following attachments: {0}".format(ats) c.log_a_msg(self.logger_queue, self.name, logmsg, "DEBUG") for next_attachment in ats: reply_attachments.append( "{0}/error_attachments/{1}".format( path_to_msg, next_attachment)) except: logmsg = "no attachments for failed task." c.log_a_msg(self.logger_queue, self.name, logmsg, "DEBUG") msg = self.assemble_email(msg, message_text, reply_attachments) self.send_out_email(recipient, msg.as_string(), message_type) self.backup_message(messageid) elif message_type == "SecAlert": ################# # SEC ALERT # ################# admin_mails = self.get_admin_emails() for admin_mail in admin_mails: msg['To'] = admin_mail path_to_msg = "users/" + user_id + "/Task" + task_nr + "/error_msg" error_msg = self.read_text_file(path_to_msg) msg['Subject'] = "Security Alert User:"******"Error report:\n\n" "" + error_msg msg = self.assemble_email(msg, message_text, '') self.send_out_email(admin_mail, msg.as_string(), message_type) self.backup_message(messageid) elif message_type == "TaskAlert": ################# # TASK ALERT # ################# admin_mails = self.get_admin_emails() for admin_mail in admin_mails: msg['To'] = admin_mail msg['Subject'] = "Task Error Alert Task " \ + task_nr + " User " + user_id message_text = "Something went wrong with task/testbench analyzation for Task " + task_nr + " and User " + user_id + " . Either the entity or testbench analyzation threw an error." msg = self.assemble_email(msg, message_text, '') self.send_out_email(admin_mail, msg.as_string(), message_type) self.backup_message(messageid) elif message_type == "Success": ################# # SUCCESS # ################# msg['Subject'] = "Task " + task_nr + " submitted successfully" message_text = "Congratulations!" msg = self.assemble_email(msg, message_text, '') self.send_out_email(recipient, msg.as_string(), message_type) #set first done if not set yet self.check_and_set_first_successful(user_id, task_nr) # last done had to be set now? --> Send Congrats if self.check_and_set_last_done(user_id): #new message, prepare it msg = MIMEMultipart() msg['From'] = self.smtp_mail msg['To'] = recipient logmsg = "RECIPIENT: " + recipient c.log_a_msg(self.logger_queue, self.name, logmsg, "DEBUG") msg['Date'] = formatdate(localtime=True) message_text = self.read_specialmessage('CONGRATS') msg['Subject'] = "Congratulations on solving all Tasks!" msg = self.assemble_email(msg, message_text, '') self.send_out_email(recipient, msg.as_string(), "LastSolved") self.backup_message(messageid) elif message_type == "Status": ################# # STATUS # ################# msg['Subject'] = "Your Current Status" message_text = self.generate_status_update(user_id, recipient, \ task_nr) numtasks = c.get_num_tasks(self.coursedb, self.logger_queue, \ self.name) if int(numtasks) >= int(task_nr): #also attach current task data = {'task_nr': str(task_nr), 'user_id': user_id} sql_cmd = "SELECT TaskAttachments FROM UserTasks WHERE TaskNr == :task_nr AND UserId == :user_id;" curs.execute(sql_cmd, data) res = curs.fetchone() logmsg = "got the following attachments: " + str(res) c.log_a_msg(self.logger_queue, self.name, logmsg, "DEBUG") if res: attachments = str(res[0]).split() msg = self.assemble_email(msg, message_text, attachments) self.send_out_email(recipient, msg.as_string(), message_type) self.backup_message(messageid) else: msg = self.assemble_email(msg, message_text, attachments) self.send_out_email(recipient, msg.as_string(), message_type) self.backup_message(messageid) elif message_type == "InvalidTask": ################# # INVALID TASK # ################# msg['Subject'] = "Invalid Task Number" message_text = self.read_specialmessage('INVALID') msg = self.assemble_email(msg, message_text, '') self.send_out_email(recipient, msg.as_string(), message_type) self.backup_message(messageid) elif message_type == "SkipNotPossible": ###################### # SKIP NOT POSSIBLE # ###################### msg['Subject'] = "Requested Skip not possible" message_text = self.read_specialmessage('SKIPNOTPOSSIBLE') msg = self.assemble_email(msg, message_text, '') self.send_out_email(recipient, msg.as_string(), message_type) self.backup_message(messageid) elif message_type == "TaskNotSubmittable": ######################### # TASK NOT SUBMITTABLE # ######################### msg['Subject'] = "Submission for this task not possible" message_text = self.read_specialmessage('TASKNOTSUBMITTABLE') msg = self.assemble_email(msg, message_text, '') self.send_out_email(recipient, msg.as_string(), message_type) self.backup_message(messageid) elif message_type == "CurLast": ################# # CUR LAST # ################# # we still need to increment the users task counter! c.user_set_current_task(self.semesterdb, task_nr, user_id, \ self.logger_queue, self.name) msg['Subject'] = "Task{0} is not available yet".format( str(task_nr)) message_text = self.read_specialmessage('CURLAST') message_text = "{0}\n\nThe Task is currently scheduled for: {1}".format(message_text, \ c.get_task_starttime(self.coursedb, str(task_nr), \ self.logger_queue, self.name)) msg = self.assemble_email(msg, message_text, '') self.send_out_email(recipient, msg.as_string(), message_type) self.backup_message(messageid) elif message_type == "DeadTask": ################# # DEAD TASK # ################# msg['Subject'] = "Deadline for Task{0} has passed.".format( str(task_nr)) message_text = self.read_specialmessage('DEADTASK') msg = self.assemble_email(msg, message_text, '') self.send_out_email(recipient, msg.as_string(), message_type) self.backup_message(messageid) elif message_type == "Usage": ################# # USAGE # ################# msg['Subject'] = "Usage" message_text = self.read_specialmessage('USAGE') msg = self.assemble_email(msg, message_text, '') self.send_out_email(recipient, msg.as_string(), message_type) self.backup_message(messageid) elif message_type == "Question": ################# # QUESTION # ################# msg['Subject'] = "Question received" message_text = self.read_specialmessage('QUESTION') msg = self.assemble_email(msg, message_text, '') self.send_out_email(recipient, msg.as_string(), message_type) self.backup_message(messageid) elif message_type == "QFwd": ################# # QFWD # ################# orig_mail = next_send_msg.get('Body') msg['Subject'] = "Question from " + orig_mail['from'] if orig_mail.get_content_maintype() == 'multipart': part = orig_mail.get_payload(0) mbody = part.get_payload() message_text = "Original subject: " + orig_mail[ 'subject'] + "\n\nNote: This e-mail contained attachments which have been removed!\n" message_text = "{0}\n\nOriginal body:\n{1}".format( message_text, mbody) else: mbody = orig_mail.get_payload() message_text = "Original subject: " + orig_mail['subject'] + \ "\n\nOriginal body:\n" + str(mbody) msg = self.assemble_email(msg, message_text, '') self.send_out_email(recipient, msg.as_string(), message_type) self.backup_message(messageid) elif message_type == "Welcome": ################# # WELCOME # ################# msg['Subject'] = "Welcome!" message_text = self.read_specialmessage('WELCOME') msg = self.assemble_email(msg, message_text, '') self.send_out_email(recipient, msg.as_string(), message_type) self.backup_message(messageid) elif message_type == "RegOver": ################# # REGOVER # ################# msg['Subject'] = "Registration Deadline has passed" message_text = self.read_specialmessage('REGOVER') msg = self.assemble_email(msg, message_text, '') self.send_out_email(recipient, msg.as_string(), message_type) self.backup_message(messageid) elif message_type == "NotAllowed": ################# # NOT ALLOWED # ################# msg['Subject'] = "Registration Not Successful." message_text = self.read_specialmessage('NOTALLOWED') msg = self.assemble_email(msg, message_text, '') self.send_out_email(recipient, msg.as_string(), message_type) self.backup_message(messageid) else: ################# # UNKNOWN # ################# c.log_a_msg(self.logger_queue, self.name, \ "Unkown Message Type in the sender_queue!", "ERROR") msg = self.assemble_email(msg, message_text, '') self.send_out_email(recipient, msg.as_string(), message_type) self.backup_message(messageid) cons.close() conc.close()
def handle_next_mail(self): """ parse the subject/content of a mail and take appropriate action. """ #blocking wait on sender_queue next_send_msg = self.sender_queue.get(True) tasknr = str(next_send_msg.get('Task')) messageid = str(next_send_msg.get('MessageId')) uid = str(next_send_msg.get('UserId')) recipient = str(next_send_msg.get('recipient')) message_type = str(next_send_msg.get('message_type')) curs, cons = c.connect_to_db(self.semesterdb, self.logger_queue, \ self.name) curc, conc = c.connect_to_db(self.coursedb, self.logger_queue, \ self.name) attachments = [] # prepare fields for the e-mail msg = MIMEMultipart() msg['From'] = self.mail_user msg['To'] = recipient logmsg = "RECIPIENT: " + recipient c.log_a_msg(self.logger_queue, self.name, logmsg, "DEBUG") msg['Date'] = formatdate(localtime=True) if message_type == "Task": logmsg = "Task in send_queue: " + str(next_send_msg) c.log_a_msg(self.logger_queue, self.name, logmsg, "DEBUG") numtasks = c.get_num_tasks(self.coursedb, \ self.logger_queue, self.name) ctasknr = c.user_get_current_task(self.semesterdb, uid, \ self.logger_queue, self.name) if numtasks+1 == int(tasknr): # last task solved! msg['Subject'] = "Congratulations!" message_text = self.read_specialmessage('CONGRATS') if int(tasknr)-1 == int(ctasknr): # statistics shall only be udated on the first # successful submission c.user_set_current_task(self.semesterdb, tasknr, uid, \ self.logger_queue, self.name) self.increment_db_taskcounter(curs, cons, 'NrSuccessful', \ str(int(tasknr)-1)) self.increment_db_taskcounter(curs, cons, 'NrSubmissions', \ str(int(tasknr)-1)) self.check_and_set_last_done(curs, cons, uid) msg = self.assemble_email(msg, message_text, '') self.send_out_email(recipient, msg.as_string(), message_type) else: # at least one more task to do: send out the description # only send the task description, after the first # successful submission if int(tasknr)-1 <= int(ctasknr) or int(ctasknr) == 1: msg['Subject'] = "Description Task" + str(tasknr) dl_text = "\nDeadline for this Task: {0}\n".format(c.get_task_deadline(self.coursedb, tasknr, self.logger_queue, self.name)) data = {'tasknr': str(tasknr)} sql_cmd = "SELECT PathToTask FROM TaskConfiguration WHERE TaskNr == :tasknr;" curc.execute(sql_cmd, data) paths = curc.fetchone() if not paths: logmsg = "It seems, the Path to Task {0} is not configured.".format(tasknr) c.log_a_msg(self.logger_queue, self.name, \ logmsg, "WARNING") message_text = "Sorry, but something went wrong... probably misconfiguration or missing configuration of Task {0}".format(tasknr) msg = self.assemble_email(msg, message_text, '') self.send_out_email(recipient, msg.as_string(), \ message_type) else: path_to_task = str(paths[0]) path_to_msg = path_to_task + "/description.txt" message_text = self.read_text_file(path_to_msg) \ + dl_text data = {'tasknr': str(tasknr), 'uid': uid} sql_cmd = "SELECT TaskAttachments FROM UserTasks WHERE TaskNr == :tasknr AND UserId == :uid;" curs.execute(sql_cmd, data) res = curs.fetchone() logmsg = "got the following attachments: " + str(res) c.log_a_msg(self.logger_queue, self.name, logmsg, \ "DEBUG") if res: attachments = str(res[0]).split() # statistics shall only be udated on the first # succesful submission c.user_set_current_task(self.semesterdb, tasknr, uid, \ self.logger_queue, self.name) self.increment_db_taskcounter(curs, cons, \ 'NrSuccessful', \ str(int(tasknr)-1)) self.increment_db_taskcounter(curs, cons, \ 'NrSubmissions', \ str(int(tasknr)-1)) msg = self.assemble_email(msg, message_text, \ attachments) self.send_out_email(recipient, msg.as_string(), \ message_type) self.backup_message(messageid) elif message_type == "Failed": self.increment_db_taskcounter(curs, cons, 'NrSubmissions', tasknr) path_to_msg = "users/{0}/Task{1}".format(uid, tasknr) error_msg = self.read_text_file("{0}/error_msg".format(path_to_msg)) msg['Subject'] = "Task" + tasknr + ": submission rejected" message_text = "Error report:\n\n""" + error_msg reply_attachments = [] try: logmsg = "searching attachments in: {0}/error_attachments".format(path_to_msg) c.log_a_msg(self.logger_queue, self.name, logmsg, "DEBUG") ats = os.listdir("{0}/error_attachments".format(path_to_msg)) logmsg = "got the following attachments: {0}".format(ats) c.log_a_msg(self.logger_queue, self.name, logmsg, "DEBUG") for next_attachment in ats: reply_attachments.append("{0}/error_attachments/{1}".format(path_to_msg, next_attachment)) except: logmsg = "no attachments for failed task." c.log_a_msg(self.logger_queue, self.name, logmsg, "DEBUG") msg = self.assemble_email(msg, message_text, reply_attachments) self.send_out_email(recipient, msg.as_string(), message_type) self.backup_message(messageid) elif message_type == "SecAlert": admin_mails = self.get_admin_emails() for admin_mail in admin_mails: msg['To'] = admin_mail path_to_msg = "users/"+ uid + "/Task" + tasknr + "/error_msg" error_msg = self.read_text_file(path_to_msg) msg['Subject'] = "Autosub Security Alert User:"******"Error report:\n\n""" + error_msg msg = self.assemble_email(msg, message_text, '') self.send_out_email(admin_mail, msg.as_string(), message_type) self.backup_message(messageid) elif message_type == "TaskAlert": admin_mails = self.get_admin_emails() for admin_mail in admin_mails: msg['To'] = admin_mail msg['Subject'] = "Autosub Task Error Alert Task " \ + tasknr + " User " + uid message_text = "Something went wrong with task/testbench analyzation for Task " + tasknr +" and User " + uid + " . Either the entity or testbench analyzation threw an error." msg = self.assemble_email(msg, message_text, '') self.send_out_email(admin_mail, msg.as_string(), message_type) self.backup_message(messageid) elif message_type == "Success": msg['Subject'] = "Task " + tasknr + " submitted successfully" message_text = "Congratulations!" msg = self.assemble_email(msg, message_text, '') self.send_out_email(recipient, msg.as_string(), message_type) #set first done if not set yet self.check_and_set_first_successful(curs, cons, uid, tasknr) # no backup of message -- this is done after the new task # description was sent to the user! elif message_type == "Status": msg['Subject'] = "Your Current Status" message_text = self.generate_status_update(curs, recipient) numtasks = c.get_num_tasks(self.coursedb, self.logger_queue, \ self.name) if int(numtasks) >= int(tasknr): #also attach current task data = {'tasknr': str(tasknr), 'uid': uid} sql_cmd = "SELECT TaskAttachments FROM UserTasks WHERE TaskNr == :tasknr AND UserId == :uid;" curs.execute(sql_cmd, data) res = curs.fetchone() logmsg = "got the following attachments: " + str(res) c.log_a_msg(self.logger_queue, self.name, logmsg, "DEBUG") if res: attachments = str(res[0]).split() msg = self.assemble_email(msg, message_text, attachments) self.send_out_email(recipient, msg.as_string(), message_type) else: msg = self.assemble_email(msg, message_text, attachments) self.send_out_email(recipient, msg.as_string(), message_type) self.backup_message(messageid) elif message_type == "InvalidTask": msg['Subject'] = "Invalid Task Number" message_text = self.read_specialmessage('INVALID') self.backup_message(messageid) msg = self.assemble_email(msg, message_text, '') self.send_out_email(recipient, msg.as_string(), message_type) elif message_type == "CurLast": # we still need to increment the users task counter! c.user_set_current_task(self.semesterdb, tasknr, uid, \ self.logger_queue, self.name) msg['Subject'] = "Task{0} is not available yet".format(str(tasknr)) message_text = self.read_specialmessage('CURLAST') message_text = "{0}\n\nThe Task is currently scheduled for: {1}".format(message_text, \ c.get_task_starttime(self.coursedb, str(tasknr), \ self.logger_queue, self.name)) self.backup_message(messageid) msg = self.assemble_email(msg, message_text, '') self.send_out_email(recipient, msg.as_string(), message_type) elif message_type == "DeadTask": msg['Subject'] = "Deadline for Task{0} has passed.".format(str(tasknr)) message_text = self.read_specialmessage('DEADTASK') self.backup_message(messageid) msg = self.assemble_email(msg, message_text, '') self.send_out_email(recipient, msg.as_string(), message_type) elif message_type == "Usage": msg['Subject'] = "Autosub Usage" message_text = self.read_specialmessage('USAGE') self.backup_message(messageid) msg = self.assemble_email(msg, message_text, '') self.send_out_email(recipient, msg.as_string(), message_type) elif message_type == "Question": msg['Subject'] = "Question received" message_text = self.read_specialmessage('QUESTION') self.backup_message(messageid) msg = self.assemble_email(msg, message_text, '') self.send_out_email(recipient, msg.as_string(), message_type) elif message_type == "QFwd": orig_mail = next_send_msg.get('Body') msg['Subject'] = "Question from " + orig_mail['from'] if orig_mail.get_content_maintype() == 'multipart': part = orig_mail.get_payload(0) mbody = part.get_payload() message_text = "Original subject: " + orig_mail['subject'] + "\n\nNote: This e-mail contained attachments which have been removed!\n" message_text = "{0}\n\nOriginal body:\n{1}".format(message_text, mbody) else: mbody = orig_mail.get_payload() message_text = "Original subject: " + orig_mail['subject'] + \ "\n\nOriginal body:\n" + str(mbody) self.backup_message(messageid) msg = self.assemble_email(msg, message_text, '') self.send_out_email(recipient, msg.as_string(), message_type) elif message_type == "Welcome": msg['Subject'] = "Welcome!" message_text = self.read_specialmessage('WELCOME') self.backup_message(messageid) msg = self.assemble_email(msg, message_text, '') self.send_out_email(recipient, msg.as_string(), message_type) elif message_type == "RegOver": msg['Subject'] = "Registration Deadline has passed" message_text = self.read_specialmessage('REGOVER') self.backup_message(messageid) msg = self.assemble_email(msg, message_text, '') self.send_out_email(recipient, msg.as_string(), message_type) elif message_type == "NotAllowed": msg['Subject'] = "Registration Not Successful." message_text = self.read_specialmessage('NOTALLOWED') msg = self.assemble_email(msg, message_text, '') self.send_out_email(recipient, msg.as_string(), message_type) self.backup_message(messageid) else: c.log_a_msg(self.logger_queue, self.name, \ "Unkown Message Type in the sender_queue!", "ERROR") msg = self.assemble_email(msg, message_text, '') self.send_out_email(recipient, msg.as_string(), message_type) self.backup_message(messageid) cons.close() conc.close()
def run(self): """ Thread code for the worker thread. """ logmsg = "Starting " + self.name c.log_a_msg(self.logger_queue, self.name, logmsg, "INFO") while True: logmsg = self.name + ": waiting for a new job." c.log_a_msg(self.logger_queue, self.name, logmsg, "INFO") nextjob = self.job_queue.get(True) if nextjob: tasknr = nextjob.get('taskNr') user_id = nextjob.get('UserId') user_email = nextjob.get('UserEmail') message_id = nextjob.get('MessageId') logmsg = self.name + " got a new job: {0} from the user with id: {1}".format( str(tasknr), str(user_id)) c.log_a_msg(self.logger_queue, self.name, logmsg, "INFO") # check if there is a test executable configured in the # database -- if not fall back on static test script. curc, conc = c.connect_to_db(self.coursedb, \ self.logger_queue, self.name) try: data = {'tasknr': tasknr} sql_cmd = "SELECT TestExecutable FROM TaskConfiguration WHERE TaskNr == :tasknr" curc.execute(sql_cmd, data) testname = curc.fetchone() except: logmsg = "Failed to fetch TestExecutable for TaskNr: {0}".format( tasknr) logmsg = logmsg + " from the Database! Table TaskConfiguration corrupted?" c.log_a_msg(self.logger_queue, self.name, logmsg, "ERROR") if testname != None: try: data = {'tasknr': tasknr} sql_cmd = "SELECT PathToTask FROM TaskConfiguration WHERE TaskNr == :tasknr" curc.execute(sql_cmd, data) path = curc.fetchone() scriptpath = str(path[0]) + "/" + str(testname[0]) except: # if a testname was given, then a Path should be # there as well! logmsg = "Failed to fetch Path to Tasknr: {0}".format( tasknr) logmsg = "{0} from the Database! Table TaskConfiguration corrupted?".format( logmsg) c.log_a_msg(self.logger_queue, self.name, logmsg, "ERROR") else: # in case no testname was given, we fall back to the # static directory structure scriptpath = "tasks/task" + str(tasknr) + "/./tests.sh" conc.close() # get the task parameters task_params = self.get_task_parameters(user_id, tasknr) # run the test script logmsg = "Running test script: " + scriptpath c.log_a_msg(self.logger_queue, self.name, logmsg, "INFO") command = "{0} {1} {2} \"{3}\" >> autosub.stdout 2>>autosub.stderr".format( scriptpath, user_id, tasknr, task_params) test_res = os.system(command) if test_res: # not 0 returned logmsg = "Test failed! User: {0} Task: {1}".format(user_id, \ tasknr) logmsg = logmsg + " return value:" + str(test_res) c.log_a_msg(self.logger_queue, self.name, logmsg, "INFO") c.send_email(self.sender_queue, str(user_email), \ str(user_id), "Failed", str(tasknr), "", \ str(message_id)) if test_res == 512: # Need to read up on this but os.system() returns # 256 when the script returns 1 and 512 when the script returns 2, 768 when 3! logmsg = "SecAlert: This test failed due to probable attack by user!" c.log_a_msg(self.logger_queue, self.name, logmsg, "INFO") c.send_email(self.sender_queue, str(user_email), \ str(user_id), "SecAlert", str(tasknr), "", \ str(message_id)) elif test_res == 768: logmsg = "TaskAlert: This test for TaskNr {0} and User {1} failed due an error with task/testbench analyzation!".format( tasknr, user_id) c.log_a_msg(self.logger_queue, self.name, logmsg, "INFO") c.send_email(self.sender_queue, str(user_email), \ str(user_id), "TaskAlert", str(tasknr), \ "", str(message_id)) else: # 0 returned logmsg = "Test succeeded! User: {0} Task: {1}".format( user_id, tasknr) c.log_a_msg(self.logger_queue, self.name, logmsg, "INFO") # Notify, the user that the submission was successful c.send_email(self.sender_queue, str(user_email), \ str(user_id), "Success", str(tasknr), "", \ str(message_id)) curc, conc = c.connect_to_db(self.coursedb, \ self.logger_queue, \ self.name) currenttask = int(c.user_get_current_task(self.semesterdb, \ user_id, \ self.logger_queue, \ self.name)) # Next, a new Task is generated -- but only if a new task # exists AND if a generator script exists (otherwise # static task description is assumed, AND if users current # task < the task that shall be generated (no Task has yet # been generated for this user yet). if currenttask < int(tasknr) + 1: try: data = {'tasknr': str(int(tasknr) + 1)} sql_cmd = "SELECT GeneratorExecutable FROM TaskConfiguration WHERE TaskNr == :tasknr" curc.execute(sql_cmd, data) res = curc.fetchone() except: logmsg = "Failed to fetch Generator Script for Tasknr: {0}".format( tasknr) logmsg = logmsg + "from the Database! Table TaskConfiguration corrupted?" c.log_a_msg(self.logger_queue, self.name, \ logmsg, "ERROR") finally: conc.close() task_start = c.get_task_starttime(self.coursedb, \ int(tasknr)+1, \ self.logger_queue, \ self.name) if task_start < datetime.datetime.now(): if res != None: # generator script for this task configured? logmsg = "Calling Generator Script: " + str( res[0]) c.log_a_msg(self.logger_queue, self.name, \ logmsg, "DEBUG") logmsg = "UserID {0}, UserEmail {1}".format( user_id, user_email) c.log_a_msg(self.logger_queue, self.name, \ logmsg, "DEBUG") self.gen_queue.put(dict({"user_id": str(user_id), \ "user_email": str(user_email), \ "task_nr": str(int(tasknr)+1), \ "messageid": ""})) else: c.send_email(self.sender_queue, \ str(user_email), str(user_id), \ "Task", str(int(tasknr)+1), "", \ str(message_id)) else: c.send_email(self.sender_queue, str(user_email), \ str(user_id), "CurLast", \ str(int(tasknr)+1), "", \ str(message_id))
def take_new_results(self, user_email, task_nr, mail, messageid): """ Store a new submisson in the user's directory structure. """ curs, cons = c.connect_to_db(self.semesterdb, self.logger_queue, self.name) data = {'Email': user_email} sql_cmd = "SELECT UserId FROM Users WHERE Email = :Email" curs.execute(sql_cmd, data) res = curs.fetchone() user_id = res[0] deadline = c.get_task_deadline(self.coursedb, task_nr, self.logger_queue, \ self.name) curtask = c.user_get_current_task(self.semesterdb, user_id, self.logger_queue, \ self.name) if deadline < datetime.datetime.now(): #deadline has passed! c.send_email(self.sender_queue, user_email, "", "DeadTask", str(task_nr), \ "", messageid) elif curtask < task_nr: #user is trying to submit a solution to a task although an earlier task # was not solved. c.send_email(self.sender_queue, user_email, "", "InvalidTask", str(task_nr), \ "", messageid) else: # get the user's UserId data = {'Email': user_email} sql_cmd = "SELECT UserId FROM Users WHERE Email = :Email" curs.execute(sql_cmd, data) res = curs.fetchone() user_id = res[0] # increment the submission_nr for the user submission_nr = self.increment_submission_nr(int(user_id), int(task_nr)) #create a directory for putting his submission in: detach_dir = 'users/{0}/Task{1}'.format(user_id, task_nr) ts = datetime.datetime.now() submission_dir = "/Submission{0}_{1}{2}{3}_{4}{5}{6}{7}".format(\ submission_nr, ts.year, ts.month, ts.day, ts.hour, ts.minute, \ ts.second, ts.microsecond) current_dir = detach_dir + submission_dir c.check_dir_mkdir(current_dir, self.logger_queue, self.name) # use walk to create a generator, iterate on the parts and forget # about the recursive headache for part in mail.walk(): # multipart are just containers, so skip them if part.get_content_maintype() == 'multipart': continue # is this part an attachment ? if part.get('Content-Disposition') is None: continue filename = part.get_filename() counter = 1 # if there is no filename, create one with a counter to avoid duplicates if not filename: filename = 'part-%03d%s' % (counter, 'bin') counter += 1 att_path = os.path.join(current_dir, filename) #Check if its already there if not os.path.isfile(att_path): # finally write the stuff fp = open(att_path, 'wb') fp.write(part.get_payload(decode=True)) fp.close() cmd = "rm " + detach_dir + "/*" + " 2> /dev/null" os.system(cmd) cmd = "cp -R " + current_dir + "/* " + detach_dir + " > /dev/null" os.system(cmd) # Next, let's handle the task that shall be checked, and send a job # request to the job_queue. The workers can then get it from there. self.job_queue.put(dict({"UserId": user_id, "UserEmail": user_email, \ "message_type": "Task", "taskNr": task_nr, \ "MessageId": messageid})) cons.close()
def run(self): """ Thread code for the worker thread. """ logmsg = "Starting " + self.name c.log_a_msg(self.logger_queue, self.name, logmsg, "INFO") while True: logmsg = self.name + ": waiting for a new job." c.log_a_msg(self.logger_queue, self.name, logmsg, "INFO") nextjob = self.job_queue.get(True) if nextjob: tasknr = nextjob.get("taskNr") user_id = nextjob.get("UserId") user_email = nextjob.get("UserEmail") message_id = nextjob.get("MessageId") logmsg = self.name + "got a new job: {0} from the user with id: {1}".format(str(tasknr), str(user_id)) c.log_a_msg(self.logger_queue, self.name, logmsg, "INFO") # check if there is a test executable configured in the # database -- if not fall back on static test script. curc, conc = c.connect_to_db(self.coursedb, self.logger_queue, self.name) try: data = {"tasknr": tasknr} sql_cmd = "SELECT TestExecutable FROM TaskConfiguration WHERE TaskNr == :tasknr" curc.execute(sql_cmd, data) testname = curc.fetchone() except: logmsg = "Failed to fetch TestExecutable for TaskNr: {0}".format(tasknr) logmsg = logmsg + " from the Database! Table TaskConfiguration corrupted?" c.log_a_msg(self.logger_queue, self.name, logmsg, "ERROR") if testname != None: try: data = {"tasknr": tasknr} sql_cmd = "SELECT PathToTask FROM TaskConfiguration WHERE TaskNr == :tasknr" curc.execute(sql_cmd, data) path = curc.fetchone() scriptpath = str(path[0]) + "/" + str(testname[0]) except: # if a testname was given, then a Path should be # there as well! logmsg = "Failed to fetch Path to Tasknr: {0}".format(tasknr) logmsg = "{0} from the Database! Table TaskConfiguration corrupted?".format(logmsg) c.log_a_msg(self.logger_queue, self.name, logmsg, "ERROR") else: # in case no testname was given, we fall back to the # static directory structure scriptpath = "tasks/task" + str(tasknr) + "/./tests.sh" conc.close() # get the task parameters task_params = self.get_task_parameters(user_id, tasknr) # run the test script logmsg = "Running test script: " + scriptpath c.log_a_msg(self.logger_queue, self.name, logmsg, "INFO") command = '{0} {1} {2} "{3}" >> autosub.stdout 2>>autosub.stderr'.format( scriptpath, user_id, tasknr, task_params ) test_res = os.system(command) if test_res: # not 0 returned logmsg = "Test failed! User: {0} Task: {1}".format(user_id, tasknr) logmsg = logmsg + " return value:" + str(test_res) c.log_a_msg(self.logger_queue, self.name, logmsg, "INFO") c.send_email( self.sender_queue, str(user_email), str(user_id), "Failed", str(tasknr), "", str(message_id) ) if test_res == 512: # Need to read up on this but os.system() returns # 256 when the script returns 1 and 512 when the script returns 2, 768 when 3! logmsg = "SecAlert: This test failed due to probable attack by user!" c.log_a_msg(self.logger_queue, self.name, logmsg, "INFO") c.send_email( self.sender_queue, str(user_email), str(user_id), "SecAlert", str(tasknr), "", str(message_id), ) elif test_res == 768: logmsg = "TaskAlert: This test for TaskNr {0} and User {1} failed due an error with task/testbench analyzation!".format( tasknr, user_id ) c.log_a_msg(self.logger_queue, self.name, logmsg, "INFO") c.send_email( self.sender_queue, str(user_email), str(user_id), "TaskAlert", str(tasknr), "", str(message_id), ) else: # 0 returned logmsg = "Test succeeded! User: {0} Task: {1}".format(user_id, tasknr) c.log_a_msg(self.logger_queue, self.name, logmsg, "INFO") # Notify, the user that the submission was successful c.send_email(self.sender_queue, str(user_email), str(user_id), "Success", str(tasknr), "", "") curc, conc = c.connect_to_db(self.coursedb, self.logger_queue, self.name) currenttask = int(c.user_get_current_task(self.semesterdb, user_id, self.logger_queue, self.name)) # Next, a new Task is generated -- but only if a new task # exists AND if a generator script exists (otherwise # static task description is assumed, AND if users current # task < the task that shall be generated (no Task has yet # been generated for this user yet). if currenttask < int(tasknr) + 1: try: data = {"tasknr": str(int(tasknr) + 1)} sql_cmd = "SELECT GeneratorExecutable FROM TaskConfiguration WHERE TaskNr == :tasknr" curc.execute(sql_cmd, data) res = curc.fetchone() except: logmsg = "Failed to fetch Generator Script for Tasknr: {0}".format(tasknr) logmsg = logmsg + "from the Database! Table TaskConfiguration corrupted?" c.log_a_msg(self.logger_queue, self.name, logmsg, "ERROR") finally: conc.close() task_start = c.get_task_starttime(self.coursedb, int(tasknr) + 1, self.logger_queue, self.name) if task_start < datetime.datetime.now(): if res != None: # generator script for this task configured? logmsg = "Calling Generator Script: " + str(res[0]) c.log_a_msg(self.logger_queue, self.name, logmsg, "DEBUG") logmsg = "UserID {0}, UserEmail {1}".format(user_id, user_email) c.log_a_msg(self.logger_queue, self.name, logmsg, "DEBUG") self.gen_queue.put( dict( { "user_id": str(user_id), "user_email": str(user_email), "task_nr": str(int(tasknr) + 1), "messageid": "", } ) ) else: c.send_email( self.sender_queue, str(user_email), str(user_id), "Task", str(int(tasknr) + 1), "", str(message_id), ) else: c.send_email( self.sender_queue, str(user_email), str(user_id), "CurLast", str(int(tasknr) + 1), "", str(message_id), )