cli-frontend.py 6.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240
  1. # Currently broken
  2. # TODO: Update to new API
  3. import sys
  4. from . import aggregator
  5. import shlex
  6. import os.path
  7. import readline
  8. from .backends.support import ResourceCategory, ResourceRawHTML, Quiz, ResourcePlain, ResourceLink
  9. from cmd import Cmd
  10. history_file = os.path.expanduser("~/.polyglot_history")
  11. class PolyglotCmd(Cmd):
  12. def do_authenticate(self, args):
  13. """Authenticates with a backend. Args: backend, username, password, school"""
  14. args = shlex.split(args)
  15. if len(args) != 4:
  16. print("Wrong number of args")
  17. return
  18. name = args[0]
  19. self.backend = aggregator.load_backend(name)
  20. config = {
  21. "Email": args[1],
  22. "Username": args[1],
  23. "Password": args[2],
  24. "School": args[3]
  25. }
  26. if aggregator.authenticate(self.backend, config):
  27. print("OK")
  28. else:
  29. print("Authentication failed")
  30. return
  31. course_set = self.backend.courses
  32. self.courses = {}
  33. for course in course_set:
  34. print(course.title)
  35. self.courses[course.title] = course
  36. def dump_resource(self, rsrc, expand):
  37. if isinstance(rsrc, ResourceCategory):
  38. print(rsrc.name)
  39. if expand:
  40. for child in rsrc.children:
  41. print("..." + child.name)
  42. for child in rsrc.contents:
  43. print("")
  44. self.dump_resource(child, False)
  45. elif isinstance(rsrc, ResourceRawHTML):
  46. print(rsrc.name + ": " + rsrc.html)
  47. elif isinstance(rsrc, ResourcePlain):
  48. print(rsrc.name + ": " + rsrc.text)
  49. elif isinstance(rsrc, ResourceLink):
  50. print(rsrc.name + ": " + rsrc.url)
  51. else:
  52. print(rsrc.name + " (" + type(rsrc).__name__ + ")")
  53. def find_resource(self, root, path):
  54. if len(path) == 0:
  55. return root
  56. if isinstance(root, ResourceCategory):
  57. for child in root.children:
  58. if child.name == path[0]:
  59. return self.find_resource(child, path[1:])
  60. print("Can't find " + path[0])
  61. return
  62. print("Wrong rsrc type with " + ",".join(path))
  63. def find_content(self, head, name):
  64. for c in head.contents:
  65. if c.name == name:
  66. return c
  67. print("Can't find content")
  68. def do_resources(self, args):
  69. args = shlex.split(args)
  70. if len(args) == 0:
  71. print("Must specify course")
  72. return
  73. self.dump_resource(self.find_resource(self.courses[args[0]].resources, args[1:]), True)
  74. def do_grades(self, args):
  75. args = shlex.split(args)
  76. if len(args) == 0:
  77. for course in self.backend.courses:
  78. try:
  79. print(course.title + ": " + str(course.grade_summary * 100) + "%")
  80. except AttributeError:
  81. print(course.title + ": (N/A)")
  82. else:
  83. course = self.courses[args[0]]
  84. try:
  85. for category in course.grades:
  86. print(category.name + " (" + str(category.weight * 100) + "%):")
  87. for grade in category.grades:
  88. print(" - " + grade.name + ": " + ((str(grade.grade * 100)) if grade.grade else "(N/A) ") + "%")
  89. except IOError:
  90. print("N/A")
  91. def tasks(self, course):
  92. try:
  93. for task in course.tasks:
  94. print("- " + task.name)
  95. except AttributeError:
  96. print("(tasks N/A)")
  97. def find_task(self, lst, name):
  98. for task in lst:
  99. if task.name == name:
  100. return task
  101. def do_tasks(self, args):
  102. args = shlex.split(args)
  103. if len(args) == 0:
  104. for course in self.backend.courses:
  105. print(course.title + ":")
  106. self.tasks(course)
  107. print()
  108. elif len(args) == 1:
  109. self.tasks(self.courses[args[0]])
  110. elif len(args) == 2:
  111. task = self.find_task(self.courses[args[0]].tasks, args[1])
  112. if task is None:
  113. print("Task not found")
  114. return
  115. print(task.name)
  116. print(task.due_date)
  117. rsrcs = task.resources
  118. if rsrcs is not None:
  119. for rsrc in rsrcs:
  120. self.dump_resource(rsrc, True)
  121. else:
  122. print("No resources")
  123. def do_wget(self, args):
  124. """
  125. Download file using loaded backend's session.
  126. Useful for ./export-gdoc, etc.
  127. """
  128. args = shlex.split(args)
  129. if len(args) == 0:
  130. print("Must include URL")
  131. return
  132. u = self.backend.session.get(aggregator.transform(args[0]))
  133. with open(args[1] if len(args) > 1 else "download.bin", "wb") as f:
  134. f.write(u.content)
  135. def do_curl(self, url):
  136. """
  137. Dump file using loaded backend's session.
  138. """
  139. print(self.backend.session.get(aggregator.transform(url)).text)
  140. def find_specific(self, args, t):
  141. args = shlex.split(args)
  142. if len(args) == 0:
  143. print("Must specify course")
  144. return
  145. head = self.find_resource(self.courses[args[0]].resources, args[1:-1])
  146. r = self.find_content(head, args[-1])
  147. if r is None:
  148. return None
  149. if not isinstance(r, t):
  150. print("Requested resource is not a " + t.__name__)
  151. return None
  152. return r
  153. def do_quiz(self, args):
  154. self.quiz = self.find_specific(args, Quiz)
  155. self.questions = quiz.questions()
  156. self.quiz_ptr = -1
  157. if self.questions is not None:
  158. print("Quiz loaded with " + len(self.questions) + "questions")
  159. print("Use quiznext or quizseek to begin. quizsubmit once done.")
  160. else:
  161. print("Questions not loaded")
  162. def do_quiznext(self):
  163. self.quiz_ptr = self.quiz_ptr + 1
  164. self.quiz_question(self.questions[self.quiz_ptr])
  165. def do_quizseek(self, args):
  166. self.quiz_ptr = int(args)
  167. self.quiz_question(self.questions[self.quiz_ptr])
  168. def do_quizsubmit(self):
  169. self.quiz.submit(self.questions)
  170. def do_quit(self, _):
  171. """Quits polyglot"""
  172. sys.exit(0)
  173. def preloop(self):
  174. try:
  175. readline.read_history_file(history_file)
  176. except IOError:
  177. pass
  178. def postcmd(self, _1, _2):
  179. readline.write_history_file(history_file)
  180. prompt = PolyglotCmd()
  181. prompt.prompt = "> "
  182. prompt.cmdloop()