def main(): """ Displays current time, grading method, gradepipe status, number of uploaded (but unsubmitted files), and the submitted queue. """ tamarin.printHeader("Tamarin Status") try: print('<h2>Tamarin Status</h2>') # current time # (Printed in two different formats as a way for users # to learn how to make sense of Tamarin timestamp format) print('<p><b>Current System Time:</b> ') now = datetime.datetime.now() print(tamarin.convertTimeToTimestamp(now)) print(' (<i>' + now.isoformat(' ') + '</i>)') print('</p>') # uploaded file count print('<p><b>Uploaded (but not submitted) file count:</b> ') uploaded = glob.glob(os.path.join(tamarin.UPLOADED_ROOT, '*')) print(len(uploaded)) # grade pipe status print('<p><b>Gradepipe:</b> ') if os.path.exists(tamarin.GRADEPIPE_ACTIVE): print('<small>RUNNING</small>') else: print('<small>OFF</small>') if os.path.exists(tamarin.GRADEPIPE_DISABLED): print(' <small>(DISABLED)</small>') print('</p>') # grading queue contents print('<p><b>Submitted (but not yet graded) queue:</b> ') submitted = tamarin.getSubmittedFilenames() if len(submitted) == 0: print('[empty]') else: print('<br>') for s in submitted: print('<span class="gradequeue">' + os.path.basename(s) + '</span><br>') print('</p>') except: tamarin.printError('UNHANDLED_ERROR') finally: tamarin.printFooter()
def run(self, args=None): """ Grades all files in tamarin.SUBMITTED_ROOT. Will abort with False if fileControlled and a file state indicates it should not run. If running, sets up logging for all sub-processes. Will then loop through all submitted files, running GradeFile on each one, and return True. """ import tamarin if not args: args = dict() # set up top-level Process logger in order to capture all logging topLogger = logging.getLogger('Process') handler = logging.StreamHandler() formatter = logging.Formatter(fmt='{name}-{levelname}: {message}', style='{') handler.setFormatter(formatter) topLogger.addHandler(handler) topLogger.setLevel(self.logLevel) # make sure we should even run. if self.fileControlled: if os.path.exists(tamarin.GRADEPIPE_DISABLED): self.logger.warn("GRADEPIPE_DISABLED file exists. Quitting...") return False elif os.path.exists(tamarin.GRADEPIPE_ACTIVE): self.logger.warn("GRADEPIPE_ACTIVE file exits. Quitting...") return False # dump PID into file try: self.logger.info("Started at %s.", datetime.datetime.now()) with open(tamarin.GRADEPIPE_ACTIVE, 'w') as outfile: outfile.write(str(os.getpid())) self.logger.debug("Wrote PID %d to ACTIVE file.", os.getpid()) except IOError: self.logger.exception("Could not dump PID to file.") return False # grading loop try: #loop over submitted files as long as there are more to grade gradedCount = 0 failedCount = 0 badFiles = [] gf = GradeFile() while True: # get most recent list submitted = tamarin.getSubmittedFilenames(self.gradeOnly) submitted = [f for f in submitted if f not in badFiles] if not submitted: break success = gf.run(args, os.path.basename(submitted[0])) if success: gradedCount += 1 else: failedCount += 1 if tamarin.LEAVE_PROBLEM_FILES_IN_SUBMITTED: badFiles.append(submitted[0]) # done looping self.logger.info("%d of %d files successfully graded.", gradedCount, gradedCount + failedCount) except: self.logger.exception("Crashed unexpectedly!") # cleanup PID file try: os.remove(tamarin.GRADEPIPE_ACTIVE) self.logger.debug("Removed PID %d's ACTIVE file.", os.getpid()) except: self.logger.exception("Could not clean up ACTIVE/PID file.") self.logger.info("Stopped at %s", datetime.datetime.now()) return True