This program downloads all files of a Stud.IP users current semester.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

171 lines
5.4 KiB

  1. import time
  2. import logging as log
  3. #from tqdm import tqdm
  4. import requests as req
  5. from requests.auth import HTTPBasicAuth
  6. import json
  7. class Studip:
  8. def __init__(self, chunk_size, domain, user, db):
  9. self.CHUNK_SIZE = chunk_size
  10. self.DOMAIN = domain
  11. self.USER = user
  12. self.db = db
  13. def auth_req(self, url):
  14. """Creates a request for a user.
  15. Parameter:
  16. url(string): URL to send the request to
  17. Returns:
  18. string: request
  19. """
  20. url = self.DOMAIN + url
  21. return req.get(url, auth=self.USER)
  22. def get_uid(self):
  23. """Get the user id of the user specified in the object.
  24. Returns:
  25. string: user id
  26. """
  27. rsp = self.auth_req('/api.php/user/')
  28. user_id = rsp.json()['user_id']
  29. return user_id
  30. def get_curr_semester(self):
  31. """Get the current semester of the studip instance specified in the object.
  32. Returns:
  33. string: id for current semester
  34. """
  35. rsp = self.auth_req('/api.php/semesters/')
  36. curr_time = int(str(int(time.time())))
  37. semesters = rsp.json()['collection']
  38. for sem_uri in semesters:
  39. semester = semesters[sem_uri]
  40. sem_begin = semester['begin']
  41. sem_end = semester['end']
  42. if sem_begin < curr_time < sem_end:
  43. return sem_uri
  44. return 0
  45. def get_ordered_semesters(self):
  46. """Get the a list of semesters of studip instance specified in the object.
  47. Returns:
  48. list(string): all semesters of the user
  49. """
  50. rsp = self.auth_req('/api.php/semesters/')
  51. semesters = rsp.json()['collection']
  52. order_sems = []
  53. for sem_uri in semesters:
  54. order_sems.append(sem_uri)
  55. return order_sems
  56. def get_curr_courses(self, user_id, semester):
  57. """Get the a list of semesters of studip instance specified in the object.
  58. Returns:
  59. string: id of the current semester
  60. """
  61. rsp = self.auth_req('/api.php/user/' + user_id + '/courses?limit=1000')
  62. ord_sems = self.get_ordered_semesters()
  63. courses = rsp.json()['collection']
  64. course_list = {}
  65. for course_uri in courses:
  66. course = courses[course_uri]
  67. start_sem = course['start_semester']
  68. if start_sem != None:
  69. start_ind = ord_sems.index(start_sem)
  70. else:
  71. start_ind = 100
  72. end_sem = course['end_semester']
  73. if end_sem != None:
  74. end_ind = ord_sems.index(end_sem)
  75. else:
  76. end_ind = 100
  77. curr_ind = ord_sems.index(semester)
  78. if start_ind <= curr_ind <= end_ind:
  79. course_title = course['title']
  80. log.info(course_title + " will be downloaded")
  81. course_id = course['course_id']
  82. course_list[course_id] = course_title
  83. return course_list
  84. def get_top_folder(self, course):
  85. """Retrieves the top folder id of a given course.
  86. Parameters:
  87. course (string): course to get the top folder of
  88. Returns:
  89. string: id of the top folder
  90. """
  91. rsp = self.auth_req('/api.php/course/' + course + '/top_folder')
  92. top_folder = rsp.json()
  93. tf_id = top_folder['id']
  94. return(tf_id)
  95. def get_docs(self, folder):
  96. """Get all the documents of a given folder.
  97. Parameters:
  98. folder(string): id of the folder to get documents of
  99. Returns:
  100. list(string): ids of the documents
  101. """
  102. rsp = self.auth_req('/api.php/folder/' + folder)
  103. docs = rsp.json()['file_refs']
  104. res_docs = []
  105. for doc in docs:
  106. doc_id = doc['id']
  107. res_docs.append(doc_id)
  108. return(res_docs)
  109. def download(self, doc):
  110. """Download a document.
  111. Parameters:
  112. doc (string): id of the document to download
  113. """
  114. rsp1 = self.auth_req('/api.php/file/' + doc)
  115. doc_name = rsp1.json()['name']
  116. doc_chdate = rsp1.json()['chdate']
  117. last_dl = self.db.get_last_file_dl(doc)
  118. if last_dl == None or last_dl < doc_chdate:
  119. rsp2 = self.auth_req('/api.php/file/' + doc + '/download')
  120. #total_size = int(rsp2.headers.get('content-length', 0))
  121. log.info('downloading ' + doc_name)
  122. #progbar = tqdm(total=total_size, unit='iB', unit_scale=True)
  123. try:
  124. with open(doc_name, 'wb') as doc_file:
  125. for chunk in rsp2.iter_content(self.CHUNK_SIZE):
  126. #progbar.update(len(chunk))
  127. doc_file.write(chunk)
  128. self.db.set_last_file_dl(str(doc), str(int(time.time())))
  129. except OSError:
  130. log.critical("Error while writing to the file " + doc_name)
  131. def get_subdirs(self, folder):
  132. """Get all the subdirectories of a given folder.
  133. Parameters:
  134. folder(string): id of the folder to get subdirectories of
  135. Returns:
  136. list(string): ids of the subdirectories
  137. """
  138. rsp = self.auth_req('/api.php/folder/' + folder)
  139. subdirs = rsp.json()['subfolders']
  140. res_subdirs = {}
  141. for subdir in subdirs:
  142. sub_id = subdir['id']
  143. sub_name = subdir['name']
  144. res_subdirs[sub_id] = sub_name
  145. return res_subdirs