task 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217
  1. #!/usr/bin/env python3
  2. # import modules
  3. import os
  4. import re
  5. import json
  6. import time
  7. from sys import stdout
  8. from sys import exit as byebye
  9. # global variables for reuse
  10. appName = "Task"
  11. dirName = "hello-task"
  12. homeDir = os.path.expanduser("~")
  13. targetDir = homeDir + "/.local/share/" + dirName
  14. #targetFile = targetDir + "/tasks.json"
  15. data = {}
  16. data["tasks"] = []
  17. data["settings"] = []
  18. updateMsg = ""
  19. idCounter = 1
  20. unixDay = 86400
  21. # clear screen buffer
  22. def clearScreen():
  23. os.system("cls" if os.name == "nt" else "clear")
  24. # get custom task lists
  25. clearScreen()
  26. print("Select a task list:")
  27. listOfLists = []
  28. dirContents = os.listdir(targetDir)
  29. dirContents.sort()
  30. for i in dirContents:
  31. print(len(listOfLists), i[:-5])
  32. listOfLists.append(i[:-5])
  33. inputList = input("> ")
  34. try:
  35. inputInt = int(inputList)
  36. targetFile = targetDir + "/" + listOfLists[inputInt] + ".json"
  37. except ValueError:
  38. targetFile = targetDir + "/" + inputList + ".json"
  39. # function is used by read and write functions
  40. def timeGrab():
  41. return int(time.time())
  42. # check if JSON exists, execute creation if not
  43. def jsonCheck():
  44. try:
  45. f = open(targetFile)
  46. taskList(targetFile)
  47. except:
  48. jsonCreate()
  49. # create JSON file and directory
  50. def jsonCreate():
  51. if not os.path.exists(targetDir):
  52. os.mkdir(targetDir, 0o755)
  53. data["settings"].append({
  54. "idCounter": idCounter,
  55. "lvl": 3
  56. })
  57. with open(targetFile, "w") as taskfile:
  58. json.dump(data, taskfile)
  59. taskList(targetFile)
  60. # write new content to JSON file
  61. def jsonWrite(n):
  62. global updateMsg
  63. global data
  64. global idCounter
  65. # it's important to 'try' otherwise entries that don't end in
  66. # the search string will cause massive errors
  67. try:
  68. dueTime = re.search(r'in\s+(.+?)\s+day(s\b|\b)', n, re.M|re.I)
  69. dueTemp = re.search(r'(\d+)', dueTime.group(), re.M|re.I)
  70. task = n[:-(len(dueTime.group())+1)]
  71. data["tasks"].append({
  72. "id": idCounter,
  73. "task": task,
  74. # we need to reduce the due time by one second to prevent
  75. # the timer showing a wrong due date after creation
  76. "due": timeGrab()+(int(dueTemp.group())*unixDay-1)
  77. })
  78. except:
  79. task = n
  80. data["tasks"].append({
  81. "id": idCounter,
  82. "task": task
  83. })
  84. idCounter += 1
  85. data["settings"][0]["idCounter"] = idCounter
  86. updateMsg = "[+] Added new task to list!"
  87. with open(targetFile, "w") as outfile:
  88. json.dump(data, outfile)
  89. taskList(targetFile)
  90. # remove item from JSON file
  91. def jsonRemove(n):
  92. global updateMsg
  93. # we need to make sure that we're dealing with a number
  94. try:
  95. check = int(n)
  96. for i in range(len(data["tasks"])):
  97. if data["tasks"][i]["id"] == check:
  98. data["tasks"].pop(i)
  99. with open (targetFile, "w") as outfile:
  100. json.dump(data, outfile)
  101. updateMsg = "[-] Removed task id " + n
  102. break
  103. else:
  104. updateMsg = "[!] Unable to find task id " + n
  105. except ValueError:
  106. updateMsg = "[!] Please use the id of the task"
  107. taskList(targetFile)
  108. # read JSON file into memory and print to stdout
  109. def jsonRead(content):
  110. global data
  111. global idCounter
  112. global updateMsg
  113. with open(content) as objects:
  114. data = json.load(objects)
  115. if idCounter <= 1:
  116. idCounter = data["settings"][0]["idCounter"]
  117. # this needs to sort o into lists for further displaying
  118. # as grouped items according to due date
  119. for o in data["tasks"]:
  120. print(("[" + str(o["id"]) + "] " + o["task"]))
  121. try:
  122. days = int(o["due"]) - timeGrab()
  123. days = days/24/60/60+1
  124. if days < 0:
  125. print("Overdue\n")
  126. elif days < 1:
  127. print("Due today\n")
  128. elif days < 2:
  129. print("Due tomorrow\n")
  130. else:
  131. print(("Due in " + str(int(days)) + " days\n"))
  132. except:
  133. print("Whenever you feel like it\n")
  134. # display JSON content as task list
  135. def taskList(tasks):
  136. clearScreen()
  137. jsonRead(tasks)
  138. stdout.write("\x1b]2;" + appName + "\x07")
  139. if not updateMsg == "":
  140. print(updateMsg)
  141. userInput()
  142. # await user input and add or remove tasks
  143. def userInput():
  144. global updateMsg
  145. print("Type 'help' or '?' for more info")
  146. choice = input("> ").strip()
  147. if (choice.lower() == "help") or (choice == "?"):
  148. userHelp()
  149. elif (choice.lower() == "quit") or (choice.lower() == "exit"):
  150. clearScreen()
  151. byebye
  152. elif choice.startswith(":d"):
  153. jsonRemove(choice[2:].strip())
  154. elif choice.startswith(":lvl"):
  155. settingsUpdate(choice[1:4], choice[4:5])
  156. elif choice == "":
  157. updateMsg = "[?] Not sure what to do"
  158. taskList(targetFile)
  159. else:
  160. jsonWrite(choice)
  161. # update user settings
  162. def settingsUpdate(m, n):
  163. global updateMsg
  164. updateMsg = "[+] View level at " + n
  165. taskList(targetFile)
  166. # short help print
  167. def userHelp():
  168. clearScreen()
  169. print("""
  170. I8 ,dPYb,
  171. I8 IP'`Yb
  172. 88888888 I8 8I
  173. I8 I8 8bgg,
  174. I8 ,gggg,gg ,g, I8 dP" "8
  175. I8 dP" "Y8I ,8'8, I8d8bggP"
  176. ,I8, i8' ,8I ,8' Yb I8P' "Yb,
  177. ,d88b,,d8, ,d8b,,8'_ 8) ,d8 `Yb,
  178. 8P""Y8P"Y8888P"`Y8P' "YY8P8P88P Y8
  179. """)
  180. print("A todo list application\n")
  181. print("Task allows you to quickly create to-do lists by typing them without any additional frizz. Write anything into the input field and see it added as a new item.")
  182. print("Task understands you. By using a natural suffix like 'in 3 days', Task will automatically create a timestamp and sort the added task according to it's due date.")
  183. print("Once a task is finished, you can use it's id and delete it by typing ':d id' where 'id' would be the number displayed with the task.")
  184. print("""\nAvailable commands are:
  185. :d(id) - Remove a task by ID
  186. help/? - View this screen
  187. quit/exit - exit the application""")
  188. input("\nPress return to go back...")
  189. taskList(targetFile)
  190. # execute program
  191. jsonCheck()