def load(self): v.log(1, "Loading configuration from \"%s\"" % self.filename) data = None curpath = os.getcwd() for i in range(len(curpath.split(os.path.sep))): if os.path.isfile(self.filename): self.original_dir = curpath self.new_dir = os.getcwd() break os.chdir("..") try: with open(self.filename, "r") as fp: data = json.load(fp) fp.close() except IOError: v.log(-1, "Could not load configuration. Run \"tmc init\" first!") exit(-1) if "username" in data and "password" in data: self.token = base64.b64encode(b"%s:%s" %(data["username"], self["password"])) elif "token" in data: self.token = data["token"] self.auth = {"Authorization": "Basic %s" % self.token} self.server = data["server"] if "default_course" in data: self.default_course = int(data["default_course"]) if "default_exercise" in data: self.default_exercise = int(data["default_exercise"])
def previous_exercise(self): if self.default_exercise != -1: self.default_exercise -= 1 v.log(0, "Setting default exercise ID to %d" % self.default_exercise) self.save() else: v.log(-1, "You need to set-exercise before trying to go to the previous one!")
def create_new(self): v.log(0, "Creating new configuration.") self.server = raw_input("Server url [http://tmc.mooc.fi/mooc/]: ") if len(self.server) == 0: self.server = "http://tmc.mooc.fi/mooc/" username = raw_input("Username: "******"Password: "******"%s:%s" %(username, password)) self.auth = {"Authorization": "Basic %s" % self.token} self.save()
def save(self): v.log(0, "Saving configuration file \"%s\"" % self.filename) data = {"token": self.token, "server": self.server, "default_course": self.default_course, "default_exercise": self.default_exercise} try: with open(self.filename, "w") as fp: json.dump(data, fp) fp.close() except IOError: v.log(-1, "Could not save file \"%s\"" % self.filename) exit(-1) os.chmod(self.filename, 0600)
def get_exercise(self, exercise): r = requests.get("%sexercises/%d.json" % (self.server, exercise), headers=self.auth, params={"api_version": 7}) data = self.extract_json(r) if not "error" in data: course = Course(int(data["course_id"]), data["course_name"]) exercise = Exercise(course, int(data["exercise_id"]), data["exercise_name"]) exercise.setDownloaded() exercise.setDeadline(data["deadline"], data["deadline"]) return exercise v.log(-1, "Could not find exercise %d" % exercise) return None
def test_exercise(self, exercise, callback): if exercise.downloaded == False: v.log(-1, """Can't test something you have not even downloaded. You might be in a wrong directory.""") exit(-1) v.log(0, "Testing %s locally. This will take a while." % exercise.name) # ant s = subprocess.Popen(["ant", "test", "-S"], stdout=open(os.devnull, "wb"), stderr=open(os.devnull, "wb"), cwd=os.path.join(os.getcwd(), exercise.course.name, exercise.name_week, exercise.name_name)) s.communicate() files = glob.glob("%s*.xml" % (os.path.join(exercise.course.name, exercise.name_week, exercise.name_name, "build", "test", "results") + os.sep)) for filename in files: try: with open(filename, "r") as fp: root = ET.fromstring(fp.read()) fp.close() for testcase in root.findall("testcase"): dataarr = [] for failure in testcase.findall("failure"): data = {} data["message"] = failure.get("message") data["success"] = False dataarr.append(data) callback(dataarr) except IOError: pass if len(files) == 0: v.log(-1, "Something wen't wrong with testing!") exit(-1)
def select_course(self, courses): inp = raw_input("Course number/name: ") try: inp = int(inp) except ValueError: pass for i in courses: if i.id == inp or i.name == inp: self.default_course = i.id if self.default_course != -1: self.save() inp = raw_input("Do you want to download all of the exercises from that course also [Y/n]: ") if inp.upper() == "N": exit(0) else: v.log(-1, "Could not find that course.") inp = raw_input("Try selecting a course again [Y/n]: ") if inp.upper() == "N": exit(-1) else: self.select_course(courses)
def download_exercise(self, exercise): dirname = os.path.join(exercise.course.name, exercise.name_week, exercise.name_name) tmpfile = StringIO() if os.path.isdir(dirname) and self.force == False and self.update == False: v.log(0, "Skipping \"%s\" since already extracted." % dirname) with open(os.path.join(dirname, ".tmc_exercise_id"), "w") as fp: fp.write(str(exercise.id)) fp.close() with open(os.path.join(dirname, ".tmc_course_id"), "w") as fp: fp.write(str(exercise.course.id)) fp.close() return r = requests.get("%sexercises/%d.zip" % (self.server, exercise.id), stream=True, headers=self.auth, params={"api_version": 7}) for block in r.iter_content(1024): if not block: break tmpfile.write(block) dirname = os.path.join(exercise.course.name, exercise.name_week, exercise.name_name) if self.update == True: v.log(0, "Extracting/Updating \"%s\"" % dirname) zipfp = zipfile.ZipFile(tmpfile) for i in zipfp.infolist(): if "/src/" not in i.filename: zipfp.extract(i, exercise.course.name) else: v.log(0, "Extracting \"%s\"" % dirname) zipfp = zipfile.ZipFile(tmpfile) zipfp.extractall(exercise.course.name) with open(os.path.join(dirname, ".tmc_exercise_id"), "w") as fp: fp.write(str(exercise.id)) fp.close() with open(os.path.join(dirname, ".tmc_course_id"), "w") as fp: fp.write(str(exercise.course.id)) fp.close()
def extract_json(self, request): if request is None: return json = None try: json = request.json() except ValueError: self.stopspin() if "500" in request.text: v.log(-1, "Server encountered a internal error. (500)") else: v.log(-1, "Didn't get valid JSON. This is a server problem.") exit(-1) if "error" in json: self.stopspin() v.log(-1, json["error"]) exit(-1) return json
def submit_exercise(self, exercise, callback): if exercise.downloaded == False: v.log(-1, """Can't submit something you have not even downloaded. You might be in a wrong directory.""") exit(-1) v.log(0, "Submitting %s. This will take a while." % exercise.name) v.log(1, "Zipping up") tmpfile = StringIO() dirname = os.path.join(exercise.course.name, exercise.name_week, exercise.name_name, "src") zipfp = zipfile.ZipFile(tmpfile, "w") for root, dirs, files in os.walk(dirname): for file in files: zipfp.write(os.path.join(root, file), os.path.relpath(os.path.join(root, file), os.path.join(dirname, '..')), zipfile.ZIP_DEFLATED) zipfp.close() params = {} if self.review == True: params["request_review"] = 1 if self.paste == True: params["paste"] = 0 r = requests.post("%s/exercises/%d/submissions.json" % ( self.server, exercise.id), headers = self.auth, data = {"api_version": 7, "commit": "Submit"}, params = params, files = {"submission[file]": ('submission.zip', tmpfile.getvalue())}) data = self.extract_json(r) if "submission_url" in data: v.log(1, "Successfully submitted %s.\nPlease wait." % exercise.name) v.log(1, "URL: %s" % data["submission_url"]) else: v.log(-1, "Didn't get a submission url. That's bad.") while self.check_submission_url(data["submission_url"], callback) == "processing": time.sleep(1)
def set_exercise(self, id): self.default_exercise = id v.log(0, "Setting default exercise ID to %d" % int(id)) self.save()
def unset_course(self): self.default_course = -1 v.log(0, "Resetted default course ID") self.save()
def set_course(self, id): self.default_course = id v.log(0, "Setting default course ID to %d" % int(id)) self.save()
def unset_exercise(self): self.default_exercise = -1 v.log(0, "Resetted default exercise ID") self.save()