Example #1
0
    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}))
Example #2
0
    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)
Example #3
0
    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()
Example #4
0
    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()
Example #5
0
    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()
Example #6
0
    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))
Example #7
0
    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()
Example #8
0
    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),
                            )