def initiate_next_task(self, user_id, user_email, current_task_nr, next_task_nr): """ Initiate the generation of the next task for the user if he has not got the task already and if it has already started """ if not c.is_valid_task_nr(self.dbs["course"], next_task_nr, \ self.queues["logger"], self.name): return if current_task_nr < next_task_nr: # user did not get this task yet task_start = c.get_task_starttime(self.dbs["course"], \ next_task_nr, \ self.queues["logger"], \ self.name) if task_start <= datetime.datetime.now(): # task has already started c.generate_task(self.queues["generator"], user_id, next_task_nr, user_email, "") else: c.send_email(self.queues["sender"], str(user_email), \ str(user_id), "CurLast", \ str(next_task_nr), "", "")
def a_task_is_requested(self, user_id, user_email, task_nr, message_id): """ Process a request for a certain task_nr. Check if that task exists, if it is active, and if the deadline has not passed yet. If yes put in generator queue. """ logmsg = "Processing a Task Request, UserId:{0} TaskNr:{1}"\ .format(user_id, task_nr) c.log_a_msg(self.queues["logger"], self.name, logmsg, "INFO") #task with this task_nr exists? is_task = c.is_valid_task_nr(self.dbs["course"], task_nr, self.queues["logger"], \ self.name) if not is_task: # task_nr is not valid c.send_email(self.queues["sender"], user_email, "", "InvalidTask", str(task_nr), \ "", message_id) return # get time now, deadline and starttime of task time_now = datetime.datetime.now() starttime = c.get_task_starttime(self.dbs["course"], task_nr, \ self.queues["logger"], self.name) deadline = c.get_task_deadline(self.dbs["course"], task_nr, \ self.queues["logger"], self.name) if not (starttime <= time_now): # task not active yet logmsg = ("Task not active") c.log_a_msg(self.queues["logger"], self.name, logmsg, "DEBUG") c.send_email(self.queues["sender"], user_email, "", "TaskNotActive", \ str(task_nr), "", message_id) return if deadline < time_now: # deadline passed for that task_nr! logmsg = ("Deadline passed") c.log_a_msg(self.queues["logger"], self.name, logmsg, "DEBUG") c.send_email(self.queues["sender"], user_email, "", "DeadTask", \ str(task_nr), "", message_id) return logmsg = ("Calling Generator to create" "TaskNr:{0} for UserId:{1}").format(task_nr, user_id) c.log_a_msg(self.queues["logger"], self.name, logmsg, "DEBUG") c.generate_task(self.queues["generator"], user_id, task_nr, user_email, \ message_id)
def activator_loop(self): curc, conc = c.connect_to_db(self.dbs["course"], self.queues["logger"],\ self.name) # first we need to know, which tasks are not active at the moment sql_cmd = "SELECT * FROM TaskConfiguration WHERE TaskActive = 0" curc.execute(sql_cmd) rows_tasks = curc.fetchall() # loop through all the inactive tasks for row_task in rows_tasks: task_nr = row_task[0] # check if a tasks start time has come task_start = datetime.datetime.strptime(row_task[1], c.format_string) if task_start < datetime.datetime.now(): # first, let's set the task active! data = {'task_nr': task_nr} sql_cmd = ("UPDATE TaskConfiguration SET TaskActive = 1 " "WHERE TaskNr = :task_nr") curc.execute(sql_cmd, data) conc.commit() logmsg = "Turned Task {0} to active.".format(str(task_nr)) c.log_a_msg(self.queues["logger"], self.name, logmsg, "INFO") curs, cons = c.connect_to_db(self.dbs["semester"], \ self.queues["logger"], self.name) # with allow_requests active no other measures have to be taken if self.allow_requests != "no": continue # if auto_advance is activated, all users should be # advanced to that task if self.auto_advance: data = {'task_nr': task_nr} sqlcmd = ("SELECT UserId FROM Users " "WHERE CurrentTask < :task_nr") curs.execute(sqlcmd, data) rows = curs.fetchall() users_list = [] for row in rows: users_list.append(str(row[0])) users_comma_list = ','.join(users_list) # This did not work, therefore with format: # data = {'task_nr': task_nr,\ # 'users_comma_list': users_comma_list} # sqlcmd = ("UPDATE Users SET CurrentTask = :task_nr " # " WHERE UserId IN (:users_comma_list)") # curs.execute(sqlcmd, data) sqlcmd = ("UPDATE Users SET CurrentTask = {0} WHERE " "UserId in ({1});").format( task_nr, users_comma_list) curs.execute(sqlcmd) cons.commit() logmsg = "Advanced users with ids: " + users_comma_list c.log_a_msg(self.queues["logger"], self.name, logmsg, "INFO") # next, check if any users are waiting for that task, meaning: # 1) his CurrentTask = task_nr AND 2) No UserTask exists for it #TODO: Find a better solution with a join data = {'task_nr': task_nr} sqlcmd = ("SELECT UserId, Email FROM Users " "WHERE CurrentTask = :task_nr AND UserId NOT IN " "(SELECT UserId FROM UserTasks " "WHERE TaskNr = :task_nr)") curs.execute(sqlcmd, data) rows = curs.fetchall() for row in rows: user_id = row[0] user_email = row[1] logmsg = "The next task({0}) is sent to User {1} now." \ .format(task_nr, user_id) c.log_a_msg(self.queues["logger"], self.name, logmsg, "INFO") try: data = {'task_nr': task_nr} sql_cmd = ( "SELECT GeneratorExecutable FROM TaskConfiguration " "WHERE TaskNr = :task_nr") curc.execute(sql_cmd, data) res = curc.fetchone() except: logmsg = ( "Failed to fetch Generator Script for" "TaskNr {0} from the Database! Table " "TaskConfiguration corrupted?").format(task_nr) c.log_a_msg(self.queues["logger"], self.name, \ logmsg, "ERROR") if res != None: logmsg = "Calling Generator Script: {0}".format(res[0]) c.log_a_msg(self.queues["logger"], self.name, \ logmsg, "DEBUG") logmsg = "UserEmail: {0}, TaskNr : {1}, UserId: {2},"\ .format(user_email, task_nr, user_id) c.log_a_msg(self.queues["logger"], self.name, \ logmsg, "DEBUG") c.generate_task(self.queues["generator"], user_id,\ task_nr, user_email, "") else: c.send_email(self.queues["sender"], str(user_email), \ str(user_id), "Task", str(task_nr), "", "") cons.close() # first we need to know, which tasks are active sql_cmd = "SELECT * FROM TaskConfiguration WHERE TaskActive = 1 " curc.execute(sql_cmd) rows_tasks = curc.fetchall() # loop through all the active tasks for row_task in rows_tasks: task_nr = row_task[0] task_deadline = datetime.datetime.strptime(row_task[2], c.format_string) if task_deadline < datetime.datetime.now(): data = {'task_nr': task_nr} sql_cmd = ("UPDATE TaskConfiguration SET TaskActive = 0 " "WHERE TaskNr = :task_nr") curc.execute(sql_cmd, data) conc.commit() logmsg = "Deactivated Task {0}, deadline passed.".format( str(task_nr)) c.log_a_msg(self.queues["logger"], self.name, logmsg, "INFO") conc.close()
def add_new_user(self, user_name, user_email): """ Add the necessary entries to database for a newly registered user. Call generator thread to create the first task. """ curs, cons = c.connect_to_db(self.dbs["semester"], self.queues["logger"], self.name) logmsg = 'Creating new Account: User: %s' % user_name c.log_a_msg(self.queues["logger"], self.name, logmsg, "INFO") data = { 'Name': user_name, 'Email': user_email, 'TimeNow': str(int(time.time())) } sql_cmd = ( "INSERT INTO Users " "(UserId, Name, Email, RegisteredAt, LastDone, CurrentTask) " "VALUES(NULL, :Name, :Email, datetime(:TimeNow, 'unixepoch', 'localtime')" ", NULL, 1)") curs.execute(sql_cmd, data) cons.commit() # read back the new users UserId and create a directory for putting his # submissions in. data = {'Email': user_email} sql_cmd = "SELECT UserId FROM Users WHERE Email = :Email" curs.execute(sql_cmd, data) res = curs.fetchone() if res is None: logmsg = ("Created new user with " "name= {0} , email={1} failed").format( user_name, user_email) c.log_a_msg(self.queues["logger"], self.name, logmsg, "DEBUG") return user_id = str(res[0]) dir_name = 'users/' + user_id c.check_dir_mkdir(dir_name, self.queues["logger"], self.name) cons.close() # in allow_requests mode the user gets no first task send if self.allow_requests != "no": return # Give the user the task which is starttime <= now < deadline AND # min(TaskNr) as initial task curc, conc = c.connect_to_db(self.dbs["course"], self.queues["logger"], self.name) data = {'TimeNow': str(int(time.time()))} sql_cmd = ( "SELECT MIN(TaskNr) FROM TaskConfiguration " "WHERE TaskStart <= datetime(:TimeNow, 'unixepoch','localtime') AND " "TaskDeadline > datetime(:TimeNow, 'unixepoch', 'localtime')") curc.execute(sql_cmd, data) res = curc.fetchone() conc.close() if not res or not res[0]: logmsg = ( "Error generating initial Task for UserId = {0}. Could not " "find a initial task for this user").format(user_id) c.log_a_msg(self.queues["logger"], self.name, logmsg, "ERROR") return task_nr = int(res[0]) #adjust users CurrentTask if he does not get Task with task_nr=1 if task_nr != 1: c.user_set_current_task(self.dbs["semester"], task_nr, user_id, \ self.queues["logger"], self.name) logmsg = ("Calling Generator to create" "TaskNr:{0} for UserId:{1}").format(task_nr, user_id) c.log_a_msg(self.queues["logger"], self.name, logmsg, "DEBUG") c.generate_task(self.queues["generator"], user_id, task_nr, user_email, "")