Jt.py 6.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222
  1. import datetime
  2. import pickle
  3. import random
  4. import sys
  5. import time
  6. from hashlib import md5
  7. from os import listdir
  8. class Base:
  9. def __init__(self):
  10. self.create_time = time.time()
  11. self.create_date: datetime.datetime = datetime.datetime.utcfromtimestamp(
  12. self.create_time)
  13. self.str_time = time.strftime(
  14. "%Y%m%d%H%M%S", time.gmtime(self.create_time))
  15. self.__gene_id()
  16. def __gene_id(self):
  17. self.__id_seed: str = self.str_time + str(random.randint(10000, 99999))
  18. self.id: str = md5(self.__id_seed.encode("UTF-8")).hexdigest()
  19. class Entry(Base):
  20. def __init__(self, title: str = "未命名事项"):
  21. Base.__init__(self)
  22. if title == "未命名事项":
  23. self.title: str = title + self.str_time[4:8]
  24. else:
  25. self.title: str = title
  26. self.content: str = "在这里输入事项内容"
  27. self.set_priority()
  28. self.set_start_date()
  29. self.set_deadline(self.create_date + datetime.timedelta(days=7))
  30. self.sub_entries_dict: dict = {}
  31. def set_priority(self, priority: float = 0):
  32. if priority < -10:
  33. print("最低优先级为-10,已自动设置为-10")
  34. priority = -10.0
  35. elif priority > 10:
  36. print("最高优先级为10,已自动设置为10")
  37. priority = 10.0
  38. self.priority: float = priority
  39. def set_deadline(self, deadline_date: datetime.datetime):
  40. """This function will set the entry's deadline date
  41. Args:
  42. deadline_date (float): The deadline date must be datetime structure.
  43. Returns:
  44. bool : If successfully set the deadline will return 0, else 1.
  45. """
  46. if deadline_date < self.start_date:
  47. print("\033[1;31mERROR: Let it RIP if it's dead already\033[0m")
  48. return 1
  49. else:
  50. self.deadline = deadline_date
  51. return 0
  52. def set_start_date(self, start_date: datetime.datetime = datetime.datetime(1970, 1, 1, 0, 0, 0)):
  53. if start_date == datetime.datetime(1970, 1, 1, 0, 0, 0):
  54. self.start_date = self.create_date
  55. else:
  56. self.start_date = start_date
  57. def set_content(self, content: str):
  58. self.content = content
  59. def timestamp_converter(self, time_in):
  60. """This function can convert timestamp to date string and do reversely.
  61. Args:
  62. time_in (float/ str): Timestamp as float or date string like "YYYY/mm/dd HH:MM".
  63. Returns:
  64. timestamp or date string.
  65. """
  66. try:
  67. _time_in = float(time_in)
  68. return datetime.datetime.utcfromtimestamp(_time_in)
  69. except ValueError:
  70. return time.mktime(time.strptime(time_in, "%Y/%m/%d %H:%M"))
  71. class Coordinate(Base):
  72. def __init__(self):
  73. Base.__init__(self)
  74. self.name = "未命名坐标系" + self.str_time
  75. # Base.__gene_id(self)
  76. self.entries_dict = {}
  77. self.entries_num = 0
  78. def show_entries(self):
  79. print(self.entries_dict)
  80. def add_entry(self, entry_in: Entry):
  81. self.entries_dict[entry_in.id] = entry_in
  82. self.entries_num += 1
  83. def del_entry(self, entry_in: Entry):
  84. try:
  85. del self.entries_dict[entry_in.id]
  86. self.entries_num -= 1
  87. except KeyError:
  88. print("\033[1;31mERROR: Entry doesn't exist\033[0m")
  89. def save_coord(self):
  90. with open("coord/" + self.name + ".crd", "wb") as f:
  91. pickle.dump(self, f, pickle.HIGHEST_PROTOCOL)
  92. def __str__(self) -> str:
  93. return (
  94. "Title: "
  95. + self.name
  96. + "\nId: "
  97. + self.id
  98. + "\nEntries number: "
  99. + str(self.entries_num)
  100. )
  101. class Interface:
  102. def __init__(self):
  103. self.coordinate_dict: dict = {}
  104. self.exit: bool = False
  105. self.func_dict = {
  106. "exit": self.__exit,
  107. "open": self.__open_coord,
  108. "ls": self.__list_coord,
  109. "show": self.__show_now_coord,
  110. "entry": self.__new_entry,
  111. "chcrd": self.__coord_changer,
  112. }
  113. def start(self):
  114. print(
  115. "*******************************\n*Welcome to Jt mission manager*\n*******************************\n"
  116. )
  117. self.__coord_changer([])
  118. while not (self.exit):
  119. command = input("\033[1;32m> \033[0m").split()
  120. try:
  121. func_name = command[0]
  122. try:
  123. func = self.func_dict[func_name]
  124. func(command[1:])
  125. except KeyError:
  126. print("\033[1;31mERROR: Command not found\033[0m")
  127. except IndexError:
  128. pass
  129. def __open_coord(self, coord_file: str):
  130. with open(coord_file, "rb") as f:
  131. self.now_coord: Coordinate = pickle.load(f)
  132. def __list_coord(self):
  133. self.files = listdir("coord")
  134. if self.files:
  135. i = 0
  136. for f in self.files:
  137. print(i, f)
  138. i += 1
  139. def __save_now_coord(self):
  140. save_or_not: str = input("Save the opened coordinate? Y/n")
  141. if save_or_not in ["Y", "y", "1"]:
  142. self.now_coord.save_coord()
  143. return 0
  144. elif save_or_not in ["N", "n", "0"]:
  145. return 0
  146. else:
  147. self.__save_now_coord()
  148. def __coord_changer(self, arg: list):
  149. try:
  150. self.now_coord
  151. self.__save_now_coord()
  152. except AttributeError:
  153. pass
  154. print("Select a coordinate to open:")
  155. self.__list_coord()
  156. coord_file = self.files[
  157. int(input("\033[1;32mType in the coordinate number:\033[0m"))
  158. ]
  159. self.__open_coord("coord/" + coord_file)
  160. def __new_entry(self, arg: list):
  161. e = Entry(arg[0])
  162. print("Input the content of this entry, use \"Ctrl+D\" to end.\n")
  163. e.content = "\n".join(sys.stdin.readlines())
  164. print(e.content)
  165. def __new_coord(self, arg: list):
  166. c = Coordinate()
  167. c.name = arg[0]
  168. raise NotImplementedError
  169. def __show_now_coord(self, arg: list):
  170. print(self.now_coord)
  171. def __add_coordinate(self, c: Coordinate):
  172. if not c.id in self.coordinate_dict:
  173. self.coordinate_dict[c.id] = c
  174. else:
  175. print("\033[1;31mERROR: It's already in there\033[0m")
  176. def __exit(self, arg):
  177. self.exit = True
  178. def main():
  179. i = Interface()
  180. i.start()
  181. if __name__ == "__main__":
  182. main()