CAT-SOOP is a flexible, programmable learning management system based on the Python programming language. https://catsoop.mit.edu
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.
 
 
 

119 lines
4.1 KiB

  1. # This file is part of CAT-SOOP
  2. # Copyright (c) 2011-2020 by The CAT-SOOP Developers <catsoop-dev@mit.edu>
  3. #
  4. # This program is free software: you can redistribute it and/or modify it under
  5. # the terms of the GNU Affero General Public License as published by the Free
  6. # Software Foundation, either version 3 of the License, or (at your option) any
  7. # later version.
  8. #
  9. # This program is distributed in the hope that it will be useful, but WITHOUT
  10. # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
  11. # FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
  12. # details.
  13. #
  14. # You should have received a copy of the GNU Affero General Public License
  15. # along with this program. If not, see <http://www.gnu.org/licenses/>.
  16. import os
  17. import json
  18. import base64
  19. import mimetypes
  20. from urllib.parse import urlencode
  21. tutor.qtype_inherit("smallbox")
  22. base, _ = tutor.question("smallbox")
  23. always_rerender = True
  24. defaults.update(
  25. {
  26. "csq_soln_filename": "solution.txt",
  27. "csq_allow_save": False,
  28. "csq_soln_type": "string",
  29. "csq_extract_data": True,
  30. }
  31. )
  32. def handle_submission(submissions, **info):
  33. o = {"score": None, "msg": "", "rerender": True}
  34. name = info["csq_name"]
  35. ll = submissions.get(name, None)
  36. if ll is not None:
  37. fname, _ = ll
  38. if info["csq_extract_data"]:
  39. submissions[name] = info["csm_loader"].get_file_data(
  40. info, submissions, name
  41. )
  42. o.update(base["handle_submission"](submissions, **info))
  43. return o
  44. def render_html(last_log, **info):
  45. name = info["csq_name"]
  46. out = """<input type="file" style="display: none" id=%s name="%s" />""" % (
  47. name,
  48. name,
  49. )
  50. out += (
  51. """<button class="btn btn-catsoop" id="%s_select_button">Select File</button>&nbsp;"""
  52. """<tt><span id="%s_selected_file">No file selected</span></tt>"""
  53. ) % (name, name)
  54. out += (
  55. """<script type="text/javascript">"""
  56. "\n// @license magnet:?xt=urn:btih:0b31508aeb0634b347b8270c7bee4d411b5d4109&dn=agpl-3.0.txt AGPL-v3"
  57. """\ndocument.getElementById('%s_select_button').addEventListener('click', function (){"""
  58. """\n document.getElementById("%s").click();"""
  59. """\n});"""
  60. """\ndocument.getElementById('%s').addEventListener('change', function (){"""
  61. """\n document.getElementById('%s_selected_file').innerText = document.getElementById('%s').value;"""
  62. """\n});"""
  63. "\n// @license-end"
  64. """</script>"""
  65. ) % (name, name, name, name, name)
  66. ll = last_log.get(name, None)
  67. if ll is not None:
  68. try:
  69. fname, loc = ll
  70. loc = os.path.basename(loc)
  71. if info["csm_cslog"].ENCRYPT_KEY is not None:
  72. seed = (
  73. info["cs_path_info"][0]
  74. if info["cs_path_info"]
  75. else info["cs_path_info"]
  76. )
  77. _path = [
  78. info["csm_cslog"]._e(i, repr(seed)) for i in info["cs_path_info"]
  79. ]
  80. else:
  81. _path = info["cs_path_info"]
  82. qstring = urlencode({"path": json.dumps(_path), "fname": loc})
  83. safe_fname = (
  84. fname.replace("<", "")
  85. .replace(">", "")
  86. .replace('"', "")
  87. .replace("'", "")
  88. )
  89. out += "<br/>"
  90. out += (
  91. '<a href="%s/_util/get_upload?%s" '
  92. 'download="%s">Download Most '
  93. "Recent Submission</a>"
  94. ) % (info["cs_url_root"], qstring, safe_fname)
  95. except:
  96. pass
  97. return out
  98. def answer_display(**info):
  99. name = info["csq_soln_filename"]
  100. if info["csq_soln_type"] == "string":
  101. data = csm_thirdparty.data_uri.DataURI.make(
  102. "text/plain", None, True, info["csq_soln"]
  103. )
  104. else:
  105. data = csm_thirdparty.data_uri.DataURI.from_file(info["csq_soln"])
  106. ext = mimetypes.guess_extension(data.mimetype) or ".txt"
  107. name = name.rsplit(".", 1) + ext
  108. return ('<a href="%s" ' 'download="%s">Download Solution</a>') % (data, name)