#!/bin/python3 import sys import os import shutil import datetime import filecmp USER_ID = os.getenv("USER") SUBMISSION_BASE_DIR = "/shpc22/submission/{}/{}" COMMAND_LIST =["status", "submit", "diff", "cat", "pull"] HW_LIST = ["hw1"] FILE_LIST = { "hw1": ["report.pdf", "convert.c"] } class bcolors: HEADER = '\033[95m' OKBLUE = '\033[94m' OKCYAN = '\033[96m' OKGREEN = '\033[92m' WARNING = '\033[93m' FAIL = '\033[91m' ENDC = '\033[0m' BOLD = '\033[1m' UNDERLINE = '\033[4m' def color_text(msg, msg_type): if msg_type == "fail": msg = bcolors.FAIL + msg + bcolors.ENDC if msg_type == "ok": msg = bcolors.OKGREEN + msg + bcolors.ENDC return msg def print_usage_exit(msg=None): if msg: print(msg) print() print("Usage:") print(" shpc22-submit status") print(" shpc22-submit status [hw1|hw2|...]") print(" shpc22-submit [status|submit|diff|cat|pull] [hw1|hw2|...] filename") sys.exit(0) def verify_hw_path_dir(hw, path): if hw not in HW_LIST: print_usage_exit(f"\"{hw}\" is not a valid homework") submission_dir = SUBMISSION_BASE_DIR.format(USER_ID, hw) os.makedirs(submission_dir, exist_ok=True) fname = path.rsplit(os.path.sep)[-1] if fname not in FILE_LIST[hw]: print_usage_exit(f"\"{fname}\" is not required in \"{hw}\"") return fname def pull_file(hw, path): if os.path.exists(path): print(f"File \"{path}\" already exists") print("Do you want to proceed? (y/n)", end=" ") ans = input().rstrip().lower() if ans == "y": pass else: sys.exit(1) fname = verify_hw_path_dir(hw, path) submission_dir = SUBMISSION_BASE_DIR.format(USER_ID, hw) shutil.copy(f"{submission_dir}/{fname}", f"{path}") def cat_file(hw, path): fname = verify_hw_path_dir(hw, path) submission_dir = SUBMISSION_BASE_DIR.format(USER_ID, hw) print("".join(open(fname).readlines())) def diff_file(hw, path): if not os.path.exists(path): print_usage_exit(f"File \"{path}\" does not exist") fname = verify_hw_path_dir(hw, path) submission_dir = SUBMISSION_BASE_DIR.format(USER_ID, hw) if not os.path.exists(f"{submission_dir}/{fname}"): print_usage_exit(f"\"{fname}\" has not been submitted") if filecmp.cmp(f"{path}", f"{submission_dir}/{fname}"): print(f"{path}: ", color_text("SAME", "ok")) else: print(f"{path}: ", color_text("DIFFERENT", "fail")) def submit_file(hw, path): if not os.path.exists(path): print_usage_exit(f"File \"{path}\" does not exist") fname = verify_hw_path_dir(hw, path) submission_dir = SUBMISSION_BASE_DIR.format(USER_ID, hw) shutil.copy(f"{path}", f"{submission_dir}/{fname}") def status_file(hw, path): fname = verify_hw_path_dir(hw, path) submission_dir = SUBMISSION_BASE_DIR.format(USER_ID, hw) submission_path = f"{submission_dir}/{fname}" status = "" if not os.path.exists(submission_path): status = color_text("NOT SUBMITTED", "fail") elif os.path.getsize(submission_path) == 0: status = color_text("EMPTY FILE", "fail") else: m_time = os.path.getmtime(submission_path) m_date = datetime.datetime.fromtimestamp(m_time).strftime('%Y-%m-%d %H:%M:%S') fsize = os.path.getsize(submission_path) status = color_text("OK", "ok") + " / " + f"{fsize / 1000:.1f} KB" + " / " + str(m_date) print(f" {fname:15}: {status}") FUNCTION_LIST = { "status": status_file, "submit": submit_file, "diff": diff_file, "cat": cat_file, "pull": pull_file, } def status_hw(hw): if hw not in HW_LIST: print_usage_exit(f"\"{hw}\" is not a valid homework") print(f"{hw}") for path in FILE_LIST[hw]: status_file(hw, path) def status_all(): for hw in HW_LIST: status_hw(hw) if __name__ == "__main__": if len(sys.argv) < 2 or sys.argv[1] not in COMMAND_LIST: print_usage_exit() user_submission_dir = "/shpc22/submission/{}".format(USER_ID) if not os.path.exists(user_submission_dir): print_usage_exit(f"You ({USER_ID}) are not registered to the course.") command = sys.argv[1] if command not in COMMAND_LIST: print_usage_exit(f"Unknown command: {command}") if len(sys.argv) == 2: if command == "status": status_all() else: print_usage_exit(f"Illegal usage: \"{sys.argv[1]}\"") elif len(sys.argv) == 3: if command == "status": status_hw(sys.argv[2]) else: print_usage_exit(f"Illegal usage: \"{sys.argv[1]} {sys.argv[2]}\"") else: FUNCTION_LIST[command](sys.argv[2], sys.argv[3])