from sys import flags from color_printing import ERROR, INFO, STATUS, WARNING, cstr, log_print import datetime import pickle import random import sys import time from hashlib import md5 from os import listdir class Base: def __init__(self): self.create_time = time.time() self.create_date: datetime.datetime = datetime.datetime.utcfromtimestamp( self.create_time) self.str_time = time.strftime( "%Y%m%d%H%M%S", time.gmtime(self.create_time)) self.__gene_id() def __gene_id(self): self.__id_seed: str = self.str_time + str(random.randint(10000, 99999)) self.id: str = md5(self.__id_seed.encode("UTF-8")).hexdigest() class Entry(Base): def __init__(self, title: str = "未命名事项"): Base.__init__(self) if title == "未命名事项": self.title: str = title + self.str_time[4:8] else: self.title: str = title self.__content: str = "事项内容" self.set_priority() self.set_start_date() self.set_deadline(self.create_date + datetime.timedelta(days=7)) self.time_total : datetime.timedelta = self.deadline-self.start_date self.time_left : datetime.timedelta = self.deadline - datetime.datetime.today() # self.sub_entries_dict: dict = {} def set_priority(self, priority: float = 0): if priority < -10: print("最低优先级为-10,已自动设置为-10") priority = -10.0 elif priority > 10: print("最高优先级为10,已自动设置为10") priority = 10.0 self.priority: float = priority def set_deadline(self, deadline_date: datetime.datetime): """This function will set the entry's deadline date Args: deadline_date (float): The deadline date must be datetime structure. Returns: bool : If successfully set the deadline will return 0, else 1. """ if deadline_date < self.start_date: print("\033[1;31mERROR: Let it RIP if it's dead already\033[0m") return 1 else: self.deadline = deadline_date return 0 def set_start_date(self, start_date: datetime.datetime = datetime.datetime(1970, 1, 1, 0, 0, 0)): if start_date == datetime.datetime(1970, 1, 1, 0, 0, 0): self.start_date = self.create_date else: self.start_date = start_date def set_content(self, content: str): self.__content = content def timestamp_converter(self, time_in): """This function can convert timestamp to date string and do reversely. Args: time_in (float/ str): Timestamp as float or date string like "YYYY/mm/dd HH:MM". Returns: timestamp or date string. """ try: _time_in = float(time_in) return datetime.datetime.utcfromtimestamp(_time_in) except ValueError: return time.mktime(time.strptime(time_in, "%Y/%m/%d %H:%M")) def str_to_date(self, date_in: str) -> datetime.datetime: """Convert date string like "%Y/%m/%d %H:%M" or "%Y/%m/%d %H:%M" to datetime structure Args: date_in (str): "%Y/%m/%d %H:%M", 2020/07/03 18:23 Returns: datetime """ try: date = datetime.datetime.strptime(date_in, "%Y/%m/%d") return date except ValueError: date = datetime.datetime.strptime(date_in, "%Y/%m/%d %H:%M") return date def date_input(self) -> datetime.datetime: while 1: try: str_in = input( cstr("Type in the date (%Y/%m/%d or %Y/%m/%d %H:%M): ", "g")) date :datetime.datetime = self.str_to_date(str_in) return date except: print("Care the correct date format.") class Coordinate(Base): def __init__(self): Base.__init__(self) self.name = "未命名坐标系" + self.str_time # Base.__gene_id(self) self.entries_dict = {} self.entries_num = 0 def show_entries(self): print(self.entries_dict) def add_entry(self, entry_in: Entry): self.entries_dict[entry_in.id] = entry_in self.entries_num += 1 def del_entry(self, entry_in: Entry): try: del self.entries_dict[entry_in.id] self.entries_num -= 1 except KeyError: print("\033[1;31mERROR: Entry doesn't exist\033[0m") def save_coord(self): with open("coord/" + self.name + ".crd", "wb") as f: pickle.dump(self, f, pickle.HIGHEST_PROTOCOL) def __str__(self) -> str: return ( "Title: " + self.name + "\nId: " + self.id + "\nEntries number: " + str(self.entries_num) ) class Interface: def __init__(self): self.coordinate_dict: dict = {} self.exit: bool = False self.func_dict = { "exit": self.__exit, "open": self.__open_coord, "ls": self.__list_coord, "show": self.__show_now_coord, "entry": self.__new_entry, "chcrd": self.__coord_changer, } self.command_list: list = list(self.func_dict.keys()) def start(self): try: print( "*******************************\n*Welcome to Jt mission manager*\n*******************************\n" ) try: import completer completer.start_completer(self.command_list) log_print(STATUS, 'Auto complete: ON') # print("\033[1;32mAuto complete: ON\033[0m") except ModuleNotFoundError: log_print(WARNING, 'Auto complete: OFF. Module Not Found') # print("\033[1;31mWARNING: Auto complete: OFF. Module Not Found\033[0m") self.__coord_changer([]) while not (self.exit): command = input("\033[1;32m> \033[0m").split() try: func_name = command[0] try: func = self.func_dict[func_name] func(command[1:]) except KeyError: print("\033[1;31mERROR: Command not found\033[0m") except IndexError: pass except KeyboardInterrupt: self.__exit(1) def __open_coord(self, coord_file: str): with open(coord_file, "rb") as f: self.now_coord: Coordinate = pickle.load(f) def __list_coord(self, arg): """Detect the coord folder if there are any files. Args: arg (none): Meaningless, just give 1 or anything Returns: int: If multiple files exist, return 0, if empty, return -1, if only one, return 1. """ self.files = listdir("coord") if len(self.files) == 1: print(cstr(f"Only one coordinate was found.\n{self.files}", 'y')) return 1 if self.files: i = 0 for f in self.files: print(i, f) i += 1 return 0 else: return -1 def __coord_changer(self, arg: list): try: self.now_coord self.__save_now_coord() except AttributeError: pass list_result = self.__list_coord(0) if list_result==0: print("Select a coordinate to open:") coord_file = self.files[ int(input("\033[1;32mType in the coordinate number:\033[0m")) ] self.__open_coord("coord/" + coord_file) elif list_result==1: print(cstr("Opening default coordinate.",'b')) self.__open_coord('coord/'+ self.files[0]) elif list_result==-1: print(cstr('No coordinate exist','r')) def __save_now_coord(self, save_withou_asking:bool = False): if save_withou_asking: save_or_not = 'y' else: save_or_not: str = input("Save the opened coordinate? Y/n") if save_or_not in ["Y", "y", "1"]: self.now_coord.save_coord() return 0 elif save_or_not in ["N", "n", "0"]: return 0 else: self.__save_now_coord() def __new_entry(self, arg: list): e = Entry(arg[0]) e.set_deadline(e.date_input()) print(cstr("Input the content of this entry, use \"Ctrl+D\" to end.\n", 'g')) e.content = "\n".join(sys.stdin.readlines()) print(e.content) print(e.time_left) def __new_coord(self, arg: list): c = Coordinate() c.name = arg[0] raise NotImplementedError def __show_now_coord(self, arg: list): print(self.now_coord) def __add_coordinate(self, c: Coordinate): if not c.id in self.coordinate_dict: self.coordinate_dict[c.id] = c else: print("\033[1;31mERROR: It's already in there\033[0m") def __exit(self, arg): log_print(WARNING, "Exiting...") self.__save_now_coord(True) log_print(INFO, "Coordinate saved.") self.exit = True def main(): i = Interface() i.start() if __name__ == "__main__": main()