otree 6.0.0b32__tar.gz → 6.0.0b33__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (261) hide show
  1. {otree-6.0.0b32/otree.egg-info → otree-6.0.0b33}/PKG-INFO +1 -1
  2. {otree-6.0.0b32 → otree-6.0.0b33}/otree/__init__.py +1 -1
  3. {otree-6.0.0b32 → otree-6.0.0b33}/otree/api.pyi +2 -2
  4. {otree-6.0.0b32 → otree-6.0.0b33}/otree/currency.py +18 -1
  5. {otree-6.0.0b32 → otree-6.0.0b33}/otree/database.py +8 -2
  6. {otree-6.0.0b32 → otree-6.0.0b33}/otree/decimal.py +9 -1
  7. {otree-6.0.0b32 → otree-6.0.0b33}/otree/export.py +26 -1
  8. {otree-6.0.0b32 → otree-6.0.0b33}/otree/forms/widgets.py +1 -1
  9. {otree-6.0.0b32 → otree-6.0.0b33}/otree/main.py +26 -0
  10. {otree-6.0.0b32 → otree-6.0.0b33}/otree/session.py +8 -2
  11. {otree-6.0.0b32 → otree-6.0.0b33}/otree/settings.py +27 -0
  12. {otree-6.0.0b32 → otree-6.0.0b33}/otree/static/otree/js/session_data.js +6 -6
  13. {otree-6.0.0b32 → otree-6.0.0b33}/otree/templates/otree/SessionData.html +3 -3
  14. {otree-6.0.0b32 → otree-6.0.0b33}/otree/views/admin.py +4 -4
  15. {otree-6.0.0b32 → otree-6.0.0b33/otree.egg-info}/PKG-INFO +1 -1
  16. {otree-6.0.0b32 → otree-6.0.0b33}/LICENSE +0 -0
  17. {otree-6.0.0b32 → otree-6.0.0b33}/MANIFEST.in +0 -0
  18. {otree-6.0.0b32 → otree-6.0.0b33}/README.rst +0 -0
  19. {otree-6.0.0b32 → otree-6.0.0b33}/otree/api.py +0 -0
  20. {otree-6.0.0b32 → otree-6.0.0b33}/otree/asgi.py +0 -0
  21. {otree-6.0.0b32 → otree-6.0.0b33}/otree/assets/__init__.py +0 -0
  22. {otree-6.0.0b32 → otree-6.0.0b33}/otree/assets/__pycache__/__init__.cpython-310.pyc +0 -0
  23. {otree-6.0.0b32 → otree-6.0.0b33}/otree/assets/__pycache__/__init__.cpython-311.pyc +0 -0
  24. {otree-6.0.0b32 → otree-6.0.0b33}/otree/assets/app_template/MyPage.html +0 -0
  25. {otree-6.0.0b32 → otree-6.0.0b33}/otree/assets/app_template/Results.html +0 -0
  26. {otree-6.0.0b32 → otree-6.0.0b33}/otree/assets/app_template/__init__.py +0 -0
  27. {otree-6.0.0b32 → otree-6.0.0b33}/otree/assets/app_template/__pycache__/__init__.cpython-310.pyc +0 -0
  28. {otree-6.0.0b32 → otree-6.0.0b33}/otree/assets/app_template/__pycache__/__init__.cpython-311.pyc +0 -0
  29. {otree-6.0.0b32 → otree-6.0.0b33}/otree/assets/app_template_trials/Results.html +0 -0
  30. {otree-6.0.0b32 → otree-6.0.0b33}/otree/assets/app_template_trials/Task.html +0 -0
  31. {otree-6.0.0b32 → otree-6.0.0b33}/otree/assets/app_template_trials/__init__.py +0 -0
  32. {otree-6.0.0b32 → otree-6.0.0b33}/otree/assets/app_template_trials/__pycache__/__init__.cpython-310.pyc +0 -0
  33. {otree-6.0.0b32 → otree-6.0.0b33}/otree/assets/app_template_trials/__pycache__/__init__.cpython-311.pyc +0 -0
  34. {otree-6.0.0b32 → otree-6.0.0b33}/otree/assets/app_template_trials/trials.csv +0 -0
  35. {otree-6.0.0b32 → otree-6.0.0b33}/otree/assets/app_template_trials/trials.js +0 -0
  36. {otree-6.0.0b32 → otree-6.0.0b33}/otree/assets/project_template/.gitignore +0 -0
  37. {otree-6.0.0b32 → otree-6.0.0b33}/otree/assets/project_template/Procfile +0 -0
  38. {otree-6.0.0b32 → otree-6.0.0b33}/otree/assets/project_template/__init__.py +0 -0
  39. {otree-6.0.0b32 → otree-6.0.0b33}/otree/assets/project_template/__pycache__/__init__.cpython-310.pyc +0 -0
  40. {otree-6.0.0b32 → otree-6.0.0b33}/otree/assets/project_template/__pycache__/__init__.cpython-311.pyc +0 -0
  41. {otree-6.0.0b32 → otree-6.0.0b33}/otree/assets/project_template/__pycache__/settings.cpython-310.pyc +0 -0
  42. {otree-6.0.0b32 → otree-6.0.0b33}/otree/assets/project_template/__pycache__/settings.cpython-311.pyc +0 -0
  43. {otree-6.0.0b32 → otree-6.0.0b33}/otree/assets/project_template/_static/global/empty.css +0 -0
  44. {otree-6.0.0b32 → otree-6.0.0b33}/otree/assets/project_template/requirements.txt +0 -0
  45. {otree-6.0.0b32 → otree-6.0.0b33}/otree/assets/project_template/settings.py +0 -0
  46. {otree-6.0.0b32 → otree-6.0.0b33}/otree/auth.py +0 -0
  47. {otree-6.0.0b32 → otree-6.0.0b33}/otree/bots/__init__.py +0 -0
  48. {otree-6.0.0b32 → otree-6.0.0b33}/otree/bots/bot.py +0 -0
  49. {otree-6.0.0b32 → otree-6.0.0b33}/otree/bots/browser.py +0 -0
  50. {otree-6.0.0b32 → otree-6.0.0b33}/otree/bots/browser_launcher.py +0 -0
  51. {otree-6.0.0b32 → otree-6.0.0b33}/otree/bots/runner.py +0 -0
  52. {otree-6.0.0b32 → otree-6.0.0b33}/otree/channels/__init__.py +0 -0
  53. {otree-6.0.0b32 → otree-6.0.0b33}/otree/channels/consumers.py +0 -0
  54. {otree-6.0.0b32 → otree-6.0.0b33}/otree/channels/routing.py +0 -0
  55. {otree-6.0.0b32 → otree-6.0.0b33}/otree/channels/utils.py +0 -0
  56. {otree-6.0.0b32 → otree-6.0.0b33}/otree/chat.py +0 -0
  57. {otree-6.0.0b32 → otree-6.0.0b33}/otree/checks.py +0 -0
  58. {otree-6.0.0b32 → otree-6.0.0b33}/otree/cli/__init__.py +0 -0
  59. {otree-6.0.0b32 → otree-6.0.0b33}/otree/cli/base.py +0 -0
  60. {otree-6.0.0b32 → otree-6.0.0b33}/otree/cli/bots.py +0 -0
  61. {otree-6.0.0b32 → otree-6.0.0b33}/otree/cli/browser_bots.py +0 -0
  62. {otree-6.0.0b32 → otree-6.0.0b33}/otree/cli/create_session.py +0 -0
  63. {otree-6.0.0b32 → otree-6.0.0b33}/otree/cli/devserver.py +0 -0
  64. {otree-6.0.0b32 → otree-6.0.0b33}/otree/cli/devserver_inner.py +0 -0
  65. {otree-6.0.0b32 → otree-6.0.0b33}/otree/cli/prodserver.py +0 -0
  66. {otree-6.0.0b32 → otree-6.0.0b33}/otree/cli/prodserver1of2.py +0 -0
  67. {otree-6.0.0b32 → otree-6.0.0b33}/otree/cli/prodserver2of2.py +0 -0
  68. {otree-6.0.0b32 → otree-6.0.0b33}/otree/cli/resetdb.py +0 -0
  69. {otree-6.0.0b32 → otree-6.0.0b33}/otree/cli/startapp.py +0 -0
  70. {otree-6.0.0b32 → otree-6.0.0b33}/otree/cli/startapp_trials.py +0 -0
  71. {otree-6.0.0b32 → otree-6.0.0b33}/otree/cli/startproject.py +0 -0
  72. {otree-6.0.0b32 → otree-6.0.0b33}/otree/cli/timeoutsubprocess.py +0 -0
  73. {otree-6.0.0b32 → otree-6.0.0b33}/otree/cli/unzip.py +0 -0
  74. {otree-6.0.0b32 → otree-6.0.0b33}/otree/cli/zip.py +0 -0
  75. {otree-6.0.0b32 → otree-6.0.0b33}/otree/cli/zipserver.py +0 -0
  76. {otree-6.0.0b32 → otree-6.0.0b33}/otree/common.py +0 -0
  77. {otree-6.0.0b32 → otree-6.0.0b33}/otree/common2.py +0 -0
  78. {otree-6.0.0b32 → otree-6.0.0b33}/otree/constants.py +0 -0
  79. {otree-6.0.0b32 → otree-6.0.0b33}/otree/errorpage.py +0 -0
  80. {otree-6.0.0b32 → otree-6.0.0b33}/otree/forms/__init__.py +0 -0
  81. {otree-6.0.0b32 → otree-6.0.0b33}/otree/forms/fields.py +0 -0
  82. {otree-6.0.0b32 → otree-6.0.0b33}/otree/forms/forms.py +0 -0
  83. {otree-6.0.0b32 → otree-6.0.0b33}/otree/forms/multistring.py +0 -0
  84. {otree-6.0.0b32 → otree-6.0.0b33}/otree/i18n.py +0 -0
  85. {otree-6.0.0b32 → otree-6.0.0b33}/otree/live.py +0 -0
  86. {otree-6.0.0b32 → otree-6.0.0b33}/otree/locale/ar/LC_MESSAGES/django.mo +0 -0
  87. {otree-6.0.0b32 → otree-6.0.0b33}/otree/locale/ar/LC_MESSAGES/django.po +0 -0
  88. {otree-6.0.0b32 → otree-6.0.0b33}/otree/locale/babel.ini +0 -0
  89. {otree-6.0.0b32 → otree-6.0.0b33}/otree/locale/cs/LC_MESSAGES/django.mo +0 -0
  90. {otree-6.0.0b32 → otree-6.0.0b33}/otree/locale/cs/LC_MESSAGES/django.po +0 -0
  91. {otree-6.0.0b32 → otree-6.0.0b33}/otree/locale/de/LC_MESSAGES/django.mo +0 -0
  92. {otree-6.0.0b32 → otree-6.0.0b33}/otree/locale/de/LC_MESSAGES/django.po +0 -0
  93. {otree-6.0.0b32 → otree-6.0.0b33}/otree/locale/django.pot +0 -0
  94. {otree-6.0.0b32 → otree-6.0.0b33}/otree/locale/es/LC_MESSAGES/django.mo +0 -0
  95. {otree-6.0.0b32 → otree-6.0.0b33}/otree/locale/es/LC_MESSAGES/django.po +0 -0
  96. {otree-6.0.0b32 → otree-6.0.0b33}/otree/locale/fi/LC_MESSAGES/django.mo +0 -0
  97. {otree-6.0.0b32 → otree-6.0.0b33}/otree/locale/fi/LC_MESSAGES/django.po +0 -0
  98. {otree-6.0.0b32 → otree-6.0.0b33}/otree/locale/fr/LC_MESSAGES/django.mo +0 -0
  99. {otree-6.0.0b32 → otree-6.0.0b33}/otree/locale/fr/LC_MESSAGES/django.po +0 -0
  100. {otree-6.0.0b32 → otree-6.0.0b33}/otree/locale/he/LC_MESSAGES/django.mo +0 -0
  101. {otree-6.0.0b32 → otree-6.0.0b33}/otree/locale/he/LC_MESSAGES/django.po +0 -0
  102. {otree-6.0.0b32 → otree-6.0.0b33}/otree/locale/hi/LC_MESSAGES/django.mo +0 -0
  103. {otree-6.0.0b32 → otree-6.0.0b33}/otree/locale/hi/LC_MESSAGES/django.po +0 -0
  104. {otree-6.0.0b32 → otree-6.0.0b33}/otree/locale/hu/LC_MESSAGES/django.mo +0 -0
  105. {otree-6.0.0b32 → otree-6.0.0b33}/otree/locale/hu/LC_MESSAGES/django.po +0 -0
  106. {otree-6.0.0b32 → otree-6.0.0b33}/otree/locale/id/LC_MESSAGES/django.mo +0 -0
  107. {otree-6.0.0b32 → otree-6.0.0b33}/otree/locale/id/LC_MESSAGES/django.po +0 -0
  108. {otree-6.0.0b32 → otree-6.0.0b33}/otree/locale/it/LC_MESSAGES/django.mo +0 -0
  109. {otree-6.0.0b32 → otree-6.0.0b33}/otree/locale/it/LC_MESSAGES/django.po +0 -0
  110. {otree-6.0.0b32 → otree-6.0.0b33}/otree/locale/ja/LC_MESSAGES/django.mo +0 -0
  111. {otree-6.0.0b32 → otree-6.0.0b33}/otree/locale/ja/LC_MESSAGES/django.po +0 -0
  112. {otree-6.0.0b32 → otree-6.0.0b33}/otree/locale/ko/LC_MESSAGES/django.mo +0 -0
  113. {otree-6.0.0b32 → otree-6.0.0b33}/otree/locale/ko/LC_MESSAGES/django.po +0 -0
  114. {otree-6.0.0b32 → otree-6.0.0b33}/otree/locale/nb/LC_MESSAGES/django.mo +0 -0
  115. {otree-6.0.0b32 → otree-6.0.0b33}/otree/locale/nb/LC_MESSAGES/django.po +0 -0
  116. {otree-6.0.0b32 → otree-6.0.0b33}/otree/locale/nl/LC_MESSAGES/django.mo +0 -0
  117. {otree-6.0.0b32 → otree-6.0.0b33}/otree/locale/nl/LC_MESSAGES/django.po +0 -0
  118. {otree-6.0.0b32 → otree-6.0.0b33}/otree/locale/pl/LC_MESSAGES/django.mo +0 -0
  119. {otree-6.0.0b32 → otree-6.0.0b33}/otree/locale/pl/LC_MESSAGES/django.po +0 -0
  120. {otree-6.0.0b32 → otree-6.0.0b33}/otree/locale/pt/LC_MESSAGES/django.mo +0 -0
  121. {otree-6.0.0b32 → otree-6.0.0b33}/otree/locale/pt/LC_MESSAGES/django.po +0 -0
  122. {otree-6.0.0b32 → otree-6.0.0b33}/otree/locale/ru/LC_MESSAGES/django.mo +0 -0
  123. {otree-6.0.0b32 → otree-6.0.0b33}/otree/locale/ru/LC_MESSAGES/django.po +0 -0
  124. {otree-6.0.0b32 → otree-6.0.0b33}/otree/locale/tr/LC_MESSAGES/django.mo +0 -0
  125. {otree-6.0.0b32 → otree-6.0.0b33}/otree/locale/tr/LC_MESSAGES/django.po +0 -0
  126. {otree-6.0.0b32 → otree-6.0.0b33}/otree/locale/zh_Hans/LC_MESSAGES/django.mo +0 -0
  127. {otree-6.0.0b32 → otree-6.0.0b33}/otree/locale/zh_Hans/LC_MESSAGES/django.po +0 -0
  128. {otree-6.0.0b32 → otree-6.0.0b33}/otree/lookup.py +0 -0
  129. {otree-6.0.0b32 → otree-6.0.0b33}/otree/middleware.py +0 -0
  130. {otree-6.0.0b32 → otree-6.0.0b33}/otree/models/__init__.py +0 -0
  131. {otree-6.0.0b32 → otree-6.0.0b33}/otree/models/group.py +0 -0
  132. {otree-6.0.0b32 → otree-6.0.0b33}/otree/models/participant.py +0 -0
  133. {otree-6.0.0b32 → otree-6.0.0b33}/otree/models/player.py +0 -0
  134. {otree-6.0.0b32 → otree-6.0.0b33}/otree/models/session.py +0 -0
  135. {otree-6.0.0b32 → otree-6.0.0b33}/otree/models/subsession.py +0 -0
  136. {otree-6.0.0b32 → otree-6.0.0b33}/otree/models_concrete.py +0 -0
  137. {otree-6.0.0b32 → otree-6.0.0b33}/otree/mturk_client.py +0 -0
  138. {otree-6.0.0b32 → otree-6.0.0b33}/otree/patch.py +0 -0
  139. {otree-6.0.0b32 → otree-6.0.0b33}/otree/read_csv.py +0 -0
  140. {otree-6.0.0b32 → otree-6.0.0b33}/otree/room.py +0 -0
  141. {otree-6.0.0b32 → otree-6.0.0b33}/otree/static/bootstrap5/css/bootstrap.min.css +0 -0
  142. {otree-6.0.0b32 → otree-6.0.0b33}/otree/static/bootstrap5/css/bootstrap.min.css.map +0 -0
  143. {otree-6.0.0b32 → otree-6.0.0b33}/otree/static/bootstrap5/js/bootstrap.bundle.min.js +0 -0
  144. {otree-6.0.0b32 → otree-6.0.0b33}/otree/static/bootstrap5/js/bootstrap.bundle.min.js.map +0 -0
  145. {otree-6.0.0b32 → otree-6.0.0b33}/otree/static/favicon.ico +0 -0
  146. {otree-6.0.0b32 → otree-6.0.0b33}/otree/static/glyphicons/clock.png +0 -0
  147. {otree-6.0.0b32 → otree-6.0.0b33}/otree/static/glyphicons/cloud.png +0 -0
  148. {otree-6.0.0b32 → otree-6.0.0b33}/otree/static/glyphicons/cogwheel.png +0 -0
  149. {otree-6.0.0b32 → otree-6.0.0b33}/otree/static/glyphicons/delete.png +0 -0
  150. {otree-6.0.0b32 → otree-6.0.0b33}/otree/static/glyphicons/download-alt.png +0 -0
  151. {otree-6.0.0b32 → otree-6.0.0b33}/otree/static/glyphicons/eye-open.png +0 -0
  152. {otree-6.0.0b32 → otree-6.0.0b33}/otree/static/glyphicons/folder-closed.png +0 -0
  153. {otree-6.0.0b32 → otree-6.0.0b33}/otree/static/glyphicons/link.png +0 -0
  154. {otree-6.0.0b32 → otree-6.0.0b33}/otree/static/glyphicons/list-alt.png +0 -0
  155. {otree-6.0.0b32 → otree-6.0.0b33}/otree/static/glyphicons/pencil.png +0 -0
  156. {otree-6.0.0b32 → otree-6.0.0b33}/otree/static/glyphicons/plus.png +0 -0
  157. {otree-6.0.0b32 → otree-6.0.0b33}/otree/static/glyphicons/pushpin.png +0 -0
  158. {otree-6.0.0b32 → otree-6.0.0b33}/otree/static/glyphicons/refresh.png +0 -0
  159. {otree-6.0.0b32 → otree-6.0.0b33}/otree/static/glyphicons/stats.png +0 -0
  160. {otree-6.0.0b32 → otree-6.0.0b33}/otree/static/glyphicons/usd.png +0 -0
  161. {otree-6.0.0b32 → otree-6.0.0b33}/otree/static/otree/css/table.css +0 -0
  162. {otree-6.0.0b32 → otree-6.0.0b33}/otree/static/otree/css/theme2.css +0 -0
  163. {otree-6.0.0b32 → otree-6.0.0b33}/otree/static/otree/js/back_button.js +0 -0
  164. {otree-6.0.0b32 → otree-6.0.0b33}/otree/static/otree/js/common_admin.js +0 -0
  165. {otree-6.0.0b32 → otree-6.0.0b33}/otree/static/otree/js/common_user_facing.js +0 -0
  166. {otree-6.0.0b32 → otree-6.0.0b33}/otree/static/otree/js/formInputs.js +0 -0
  167. {otree-6.0.0b32 → otree-6.0.0b33}/otree/static/otree/js/internet-explorer.js +0 -0
  168. {otree-6.0.0b32 → otree-6.0.0b33}/otree/static/otree/js/jquery-3.2.1.min.js +0 -0
  169. {otree-6.0.0b32 → otree-6.0.0b33}/otree/static/otree/js/jquery.color-2.1.2.min.js +0 -0
  170. {otree-6.0.0b32 → otree-6.0.0b33}/otree/static/otree/js/jquery.countdown.min.js +0 -0
  171. {otree-6.0.0b32 → otree-6.0.0b33}/otree/static/otree/js/jquery.timeago.en-short.js +0 -0
  172. {otree-6.0.0b32 → otree-6.0.0b33}/otree/static/otree/js/jquery.timeago.js +0 -0
  173. {otree-6.0.0b32 → otree-6.0.0b33}/otree/static/otree/js/live.js +0 -0
  174. {otree-6.0.0b32 → otree-6.0.0b33}/otree/static/otree/js/page-websocket-redirect.js +0 -0
  175. {otree-6.0.0b32 → otree-6.0.0b33}/otree/static/otree/js/preserve_unsubmitted_inputs.js +0 -0
  176. {otree-6.0.0b32 → otree-6.0.0b33}/otree/static/otree/js/reconnecting-websocket-iife.min.js +0 -0
  177. {otree-6.0.0b32 → otree-6.0.0b33}/otree/static/otree/js/session_monitor.js +0 -0
  178. {otree-6.0.0b32 → otree-6.0.0b33}/otree/static/otree/js/trials-core.js +0 -0
  179. {otree-6.0.0b32 → otree-6.0.0b33}/otree/static/otree/js/trials-core.js.backup +0 -0
  180. {otree-6.0.0b32 → otree-6.0.0b33}/otree/static/otree/js/trials-pre.js +0 -0
  181. {otree-6.0.0b32 → otree-6.0.0b33}/otree/static/robots.txt +0 -0
  182. {otree-6.0.0b32 → otree-6.0.0b33}/otree/tasks.py +0 -0
  183. {otree-6.0.0b32 → otree-6.0.0b33}/otree/templates/global/Base.html +0 -0
  184. {otree-6.0.0b32 → otree-6.0.0b33}/otree/templates/global/Page.html +0 -0
  185. {otree-6.0.0b32 → otree-6.0.0b33}/otree/templates/otree/AdminReport.html +0 -0
  186. {otree-6.0.0b32 → otree-6.0.0b33}/otree/templates/otree/BaseAdminAll.html +0 -0
  187. {otree-6.0.0b32 → otree-6.0.0b33}/otree/templates/otree/BaseAdminRegular.html +0 -0
  188. {otree-6.0.0b32 → otree-6.0.0b33}/otree/templates/otree/Base_UserFacing.html +0 -0
  189. {otree-6.0.0b32 → otree-6.0.0b33}/otree/templates/otree/CreateDemoSession.html +0 -0
  190. {otree-6.0.0b32 → otree-6.0.0b33}/otree/templates/otree/CreateSession.html +0 -0
  191. {otree-6.0.0b32 → otree-6.0.0b33}/otree/templates/otree/DemoIndex.html +0 -0
  192. {otree-6.0.0b32 → otree-6.0.0b33}/otree/templates/otree/ExportIndex.html +0 -0
  193. {otree-6.0.0b32 → otree-6.0.0b33}/otree/templates/otree/FormPage.html +0 -0
  194. {otree-6.0.0b32 → otree-6.0.0b33}/otree/templates/otree/GBATInactive.html +0 -0
  195. {otree-6.0.0b32 → otree-6.0.0b33}/otree/templates/otree/Login.html +0 -0
  196. {otree-6.0.0b32 → otree-6.0.0b33}/otree/templates/otree/MTurkCreateHIT.html +0 -0
  197. {otree-6.0.0b32 → otree-6.0.0b33}/otree/templates/otree/MTurkHTMLQuestion.html +0 -0
  198. {otree-6.0.0b32 → otree-6.0.0b33}/otree/templates/otree/MTurkSessionPayments.html +0 -0
  199. {otree-6.0.0b32 → otree-6.0.0b33}/otree/templates/otree/OutOfRangeNotification.html +0 -0
  200. {otree-6.0.0b32 → otree-6.0.0b33}/otree/templates/otree/Page.html +0 -0
  201. {otree-6.0.0b32 → otree-6.0.0b33}/otree/templates/otree/RoomWelcomePage.html +0 -0
  202. {otree-6.0.0b32 → otree-6.0.0b33}/otree/templates/otree/RoomWithSession.html +0 -0
  203. {otree-6.0.0b32 → otree-6.0.0b33}/otree/templates/otree/RoomWithoutSession.html +0 -0
  204. {otree-6.0.0b32 → otree-6.0.0b33}/otree/templates/otree/Rooms.html +0 -0
  205. {otree-6.0.0b32 → otree-6.0.0b33}/otree/templates/otree/ServerCheck.html +0 -0
  206. {otree-6.0.0b32 → otree-6.0.0b33}/otree/templates/otree/Session.html +0 -0
  207. {otree-6.0.0b32 → otree-6.0.0b33}/otree/templates/otree/SessionDemoGridView.html +0 -0
  208. {otree-6.0.0b32 → otree-6.0.0b33}/otree/templates/otree/SessionDescription.html +0 -0
  209. {otree-6.0.0b32 → otree-6.0.0b33}/otree/templates/otree/SessionEditProperties.html +0 -0
  210. {otree-6.0.0b32 → otree-6.0.0b33}/otree/templates/otree/SessionMonitor.html +0 -0
  211. {otree-6.0.0b32 → otree-6.0.0b33}/otree/templates/otree/SessionPayments.html +0 -0
  212. {otree-6.0.0b32 → otree-6.0.0b33}/otree/templates/otree/SessionSplitScreen.html +0 -0
  213. {otree-6.0.0b32 → otree-6.0.0b33}/otree/templates/otree/SessionStartLinks.html +0 -0
  214. {otree-6.0.0b32 → otree-6.0.0b33}/otree/templates/otree/Sessions.html +0 -0
  215. {otree-6.0.0b32 → otree-6.0.0b33}/otree/templates/otree/WaitPage.html +0 -0
  216. {otree-6.0.0b32 → otree-6.0.0b33}/otree/templates/otree/WaitPageGeneric.html +0 -0
  217. {otree-6.0.0b32 → otree-6.0.0b33}/otree/templates/otree/includes/CreateSessionForm.html +0 -0
  218. {otree-6.0.0b32 → otree-6.0.0b33}/otree/templates/otree/includes/RoomParticipantLinks.html +0 -0
  219. {otree-6.0.0b32 → otree-6.0.0b33}/otree/templates/otree/includes/SessionInfo.html +0 -0
  220. {otree-6.0.0b32 → otree-6.0.0b33}/otree/templates/otree/includes/TimeLimit.html +0 -0
  221. {otree-6.0.0b32 → otree-6.0.0b33}/otree/templates/otree/includes/TimeLimit.js.html +0 -0
  222. {otree-6.0.0b32 → otree-6.0.0b33}/otree/templates/otree/includes/debug_info.html +0 -0
  223. {otree-6.0.0b32 → otree-6.0.0b33}/otree/templates/otree/includes/hidden_form_errors.html +0 -0
  224. {otree-6.0.0b32 → otree-6.0.0b33}/otree/templates/otree/includes/messages.html +0 -0
  225. {otree-6.0.0b32 → otree-6.0.0b33}/otree/templates/otree/includes/mturk_payment_table.html +0 -0
  226. {otree-6.0.0b32 → otree-6.0.0b33}/otree/templates/otree/includes/navbar.html +0 -0
  227. {otree-6.0.0b32 → otree-6.0.0b33}/otree/templates/otree/includes/participant_code_links_table.html +0 -0
  228. {otree-6.0.0b32 → otree-6.0.0b33}/otree/templates/otree/tags/chat.html +0 -0
  229. {otree-6.0.0b32 → otree-6.0.0b33}/otree/templating/__init__.py +0 -0
  230. {otree-6.0.0b32 → otree-6.0.0b33}/otree/templating/compiler.py +0 -0
  231. {otree-6.0.0b32 → otree-6.0.0b33}/otree/templating/context.py +0 -0
  232. {otree-6.0.0b32 → otree-6.0.0b33}/otree/templating/errors.py +0 -0
  233. {otree-6.0.0b32 → otree-6.0.0b33}/otree/templating/filters.py +0 -0
  234. {otree-6.0.0b32 → otree-6.0.0b33}/otree/templating/loader.py +0 -0
  235. {otree-6.0.0b32 → otree-6.0.0b33}/otree/templating/nodes.py +0 -0
  236. {otree-6.0.0b32 → otree-6.0.0b33}/otree/templating/template.py +0 -0
  237. {otree-6.0.0b32 → otree-6.0.0b33}/otree/templating/utils.py +0 -0
  238. {otree-6.0.0b32 → otree-6.0.0b33}/otree/test.py +0 -0
  239. {otree-6.0.0b32 → otree-6.0.0b33}/otree/trials.py +0 -0
  240. {otree-6.0.0b32 → otree-6.0.0b33}/otree/update.py +0 -0
  241. {otree-6.0.0b32 → otree-6.0.0b33}/otree/urls.py +0 -0
  242. {otree-6.0.0b32 → otree-6.0.0b33}/otree/views/__init__.py +0 -0
  243. {otree-6.0.0b32 → otree-6.0.0b33}/otree/views/abstract.py +0 -0
  244. {otree-6.0.0b32 → otree-6.0.0b33}/otree/views/cbv.py +0 -0
  245. {otree-6.0.0b32 → otree-6.0.0b33}/otree/views/demo.py +0 -0
  246. {otree-6.0.0b32 → otree-6.0.0b33}/otree/views/export.py +0 -0
  247. {otree-6.0.0b32 → otree-6.0.0b33}/otree/views/mturk.py +0 -0
  248. {otree-6.0.0b32 → otree-6.0.0b33}/otree/views/participant.py +0 -0
  249. {otree-6.0.0b32 → otree-6.0.0b33}/otree/views/querystring.py +0 -0
  250. {otree-6.0.0b32 → otree-6.0.0b33}/otree/views/rest.py +0 -0
  251. {otree-6.0.0b32 → otree-6.0.0b33}/otree/views/room.py +0 -0
  252. {otree-6.0.0b32 → otree-6.0.0b33}/otree.egg-info/SOURCES.txt +0 -0
  253. {otree-6.0.0b32 → otree-6.0.0b33}/otree.egg-info/dependency_links.txt +0 -0
  254. {otree-6.0.0b32 → otree-6.0.0b33}/otree.egg-info/entry_points.txt +0 -0
  255. {otree-6.0.0b32 → otree-6.0.0b33}/otree.egg-info/not-zip-safe +0 -0
  256. {otree-6.0.0b32 → otree-6.0.0b33}/otree.egg-info/requires.txt +0 -0
  257. {otree-6.0.0b32 → otree-6.0.0b33}/otree.egg-info/top_level.txt +0 -0
  258. {otree-6.0.0b32 → otree-6.0.0b33}/pyproject.toml +0 -0
  259. {otree-6.0.0b32 → otree-6.0.0b33}/requirements.txt +0 -0
  260. {otree-6.0.0b32 → otree-6.0.0b33}/setup.cfg +0 -0
  261. {otree-6.0.0b32 → otree-6.0.0b33}/setup.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: otree
3
- Version: 6.0.0b32
3
+ Version: 6.0.0b33
4
4
  Summary: Framework for multiplayer strategy games and complex surveys.
5
5
  Home-page: http://otree.org/
6
6
  Author: chris@otree.org
@@ -1,2 +1,2 @@
1
- __version__ = '6.0.0b32'
1
+ __version__ = '6.0.0b33'
2
2
  # don't import anything else here because setup.py imports this.
@@ -15,7 +15,7 @@ cu = Currency
15
15
  class DecimalUnit(Decimal):
16
16
  storage_places: int
17
17
  input_places: int
18
- input_units_label: str
18
+ input_unit_label: str
19
19
  output_min_places: int
20
20
  output_max_places: int
21
21
 
@@ -136,7 +136,7 @@ class models:
136
136
  def __init__(
137
137
  self,
138
138
  *,
139
- units: Type[DecimalUnit],
139
+ unit: Type[DecimalUnit],
140
140
  choices: Iterable | None = None,
141
141
  widget: Any | None = None,
142
142
  initial: AnyNumber | None = None,
@@ -164,6 +164,15 @@ class BaseCurrency(Decimal):
164
164
 
165
165
 
166
166
  class Currency(BaseCurrency):
167
+ def __new__(cls, amount):
168
+ # If CURRENCY_UNIT is defined, create instance of custom unit instead
169
+ if settings.CURRENCY_UNIT_CLASS is not None:
170
+ return settings.CURRENCY_UNIT_CLASS(amount)
171
+ # Otherwise use normal Currency behavior
172
+ if amount is None:
173
+ raise ValueError('Cannot convert None to currency')
174
+ return Decimal.__new__(cls, cls._sanitize(amount))
175
+
167
176
  @classmethod
168
177
  def get_num_decimal_places(cls):
169
178
  if settings.USE_POINTS:
@@ -209,6 +218,15 @@ class Currency(BaseCurrency):
209
218
  class RealWorldCurrency(BaseCurrency):
210
219
  '''payment currency'''
211
220
 
221
+ def __new__(cls, amount):
222
+ # If CURRENCY_UNIT is defined, create instance of custom unit instead
223
+ if settings.CURRENCY_UNIT_CLASS is not None:
224
+ return settings.CURRENCY_UNIT_CLASS(amount)
225
+ # Otherwise use normal RealWorldCurrency behavior
226
+ if amount is None:
227
+ raise ValueError('Cannot convert None to currency')
228
+ return Decimal.__new__(cls, cls._sanitize(amount))
229
+
212
230
  def to_real_world_currency(self, session):
213
231
  return self
214
232
 
@@ -260,4 +278,3 @@ def currency_range(first, last, increment):
260
278
  values.append(current_value)
261
279
  current_value += increment
262
280
 
263
-
@@ -904,15 +904,21 @@ def IntegerField(**kwargs):
904
904
 
905
905
 
906
906
  def CurrencyField(**kwargs):
907
+ # If CURRENCY_UNIT is defined, CurrencyField is an alias for DecimalField
908
+ if settings.CURRENCY_UNIT_CLASS is not None:
909
+ return DecimalField(unit=settings.CURRENCY_UNIT_CLASS, **kwargs)
907
910
  return wrap_column(CurrencyType, **kwargs)
908
911
 
909
912
 
910
913
  def RealWorldCurrencyField(**kwargs):
914
+ # If CURRENCY_UNIT is defined, RealWorldCurrencyField is an alias for DecimalField
915
+ if settings.CURRENCY_UNIT_CLASS is not None:
916
+ return DecimalField(unit=settings.CURRENCY_UNIT_CLASS, **kwargs)
911
917
  return wrap_column(RealWorldCurrencyType, **kwargs)
912
918
 
913
919
 
914
- def DecimalField(*, units, **kwargs):
915
- return wrap_column(DecimalFieldType(unit=units), **kwargs)
920
+ def DecimalField(*, unit, **kwargs):
921
+ return wrap_column(DecimalFieldType(unit=unit), **kwargs)
916
922
 
917
923
 
918
924
  # aliases for compat
@@ -16,7 +16,7 @@ class DecimalUnit(Decimal):
16
16
  # Default class attributes (should be overridden by subclasses)
17
17
  storage_places = None
18
18
  input_places = None
19
- input_units_label = ''
19
+ input_unit_label = ''
20
20
  output_min_places = None
21
21
  output_max_places = None
22
22
 
@@ -144,6 +144,14 @@ class DecimalUnit(Decimal):
144
144
  max_places = self.__class__.output_max_places
145
145
  return self._format_with_places(min_places, max_places)
146
146
 
147
+ def to_real_world_currency(self, session):
148
+ """
149
+ Compatibility method for when CurrencyField is aliased to DecimalField.
150
+ Since there's only one currency type when CURRENCY_UNIT is defined,
151
+ just return self (similar to Currency.to_real_world_currency when USE_POINTS=False)
152
+ """
153
+ return self
154
+
147
155
  def _make_result(self, result, other):
148
156
  """DRY helper for arithmetic operations"""
149
157
  if not isinstance(other, DecimalUnit):
@@ -27,6 +27,30 @@ from otree import settings
27
27
  logger = logging.getLogger(__name__)
28
28
 
29
29
 
30
+ # Single source of truth for fixed columns in SessionData view
31
+ # These columns always appear first, in this order
32
+ DATA_TAB_FIXED_COLUMNS = [
33
+ {
34
+ 'field': 'participant.label',
35
+ 'display': 'label',
36
+ 'prefix': 'pp.',
37
+ 'getter': lambda p, g, s, participant_label: participant_label,
38
+ },
39
+ {
40
+ 'field': 'group.id_in_subsession',
41
+ 'display': 'group',
42
+ 'prefix': '',
43
+ 'getter': lambda p, g, s, participant_label: g['id_in_subsession'],
44
+ },
45
+ ]
46
+
47
+ # Automatically derive the group column index
48
+ GROUP_COL_INDEX = next(
49
+ i for i, col in enumerate(DATA_TAB_FIXED_COLUMNS)
50
+ if col['field'] == 'group.id_in_subsession'
51
+ )
52
+
53
+
30
54
  def get_fields_for_monitor():
31
55
  return _get_table_fields(Participant, for_export=False)
32
56
 
@@ -85,6 +109,7 @@ def _get_table_fields(Model, custom_fields=None, for_export=False):
85
109
 
86
110
  specs = [
87
111
  ('player', BasePlayer, ['id_in_group', 'role', 'payoff']),
112
+ # group.id_in_subsession is handled separately (pushed to beginning of row)
88
113
  ('group', BaseGroup, ['id_in_subsession']),
89
114
  # don't need round_number because it's already in the SessionData navigation toolbar
90
115
  ('subsession', BaseSubsession, []),
@@ -502,7 +527,7 @@ def get_rows_for_data_tab_app(session, app_name):
502
527
  s = subsessions[p['subsession_id']]
503
528
  try:
504
529
  row = (
505
- [participant_label]
530
+ [col['getter'](p, g, s, participant_label) for col in DATA_TAB_FIXED_COLUMNS]
506
531
  + [p[fname] for fname in pfields]
507
532
  + [g[fname] for fname in gfields]
508
533
  + [s[fname] for fname in sfields]
@@ -114,7 +114,7 @@ class DecimalWidget(BaseWidget):
114
114
 
115
115
  def __init__(self, unit):
116
116
  self.unit = unit
117
- self.input_label = unit.input_units_label
117
+ self.input_label = unit.input_unit_label
118
118
  self.places = unit.input_places
119
119
 
120
120
  def get_html_fragments(self):
@@ -124,6 +124,32 @@ def setup():
124
124
 
125
125
  init_i18n(settings.LANGUAGE_CODE_ISO)
126
126
 
127
+ # Import CURRENCY_UNIT class if defined (delayed to avoid circular imports)
128
+ if settings.CURRENCY_UNIT_PATH:
129
+ import importlib
130
+ import sys
131
+ from otree.decimal import DecimalUnit
132
+
133
+ try:
134
+ module_path, class_name = settings.CURRENCY_UNIT_PATH.rsplit('.', 1)
135
+ module = importlib.import_module(module_path)
136
+ currency_unit_class = getattr(module, class_name)
137
+
138
+ # Validate it's a DecimalUnit subclass
139
+ if not issubclass(currency_unit_class, DecimalUnit):
140
+ msg = (
141
+ f"CURRENCY_UNIT must be a subclass of DecimalUnit, "
142
+ f"but {settings.CURRENCY_UNIT_PATH} is not."
143
+ )
144
+ sys.exit(msg)
145
+
146
+ # Set it globally - Currency/RealWorldCurrency __new__ will use this
147
+ settings.CURRENCY_UNIT_CLASS = currency_unit_class
148
+
149
+ except (ValueError, ImportError, AttributeError) as e:
150
+ msg = f"Failed to import CURRENCY_UNIT '{settings.CURRENCY_UNIT_PATH}': {e}"
151
+ sys.exit(msg)
152
+
127
153
  from otree.database import init_orm # noqa
128
154
 
129
155
  check_for_sentry()
@@ -76,7 +76,12 @@ class SessionConfig(dict):
76
76
  return num_cases
77
77
 
78
78
  def clean(self):
79
- for k in ['participation_fee', 'real_world_currency_per_point']:
79
+ required_keys = ['participation_fee']
80
+ # When CURRENCY_UNIT is defined, there's no currency conversion (like USE_POINTS=False)
81
+ if settings.CURRENCY_UNIT_CLASS is None:
82
+ required_keys.append('real_world_currency_per_point')
83
+
84
+ for k in required_keys:
80
85
  if k not in self:
81
86
  msg = f'SESSION_CONFIG_DEFAULTS is missing {k}'
82
87
  raise SessionConfigError(msg)
@@ -127,7 +132,8 @@ class SessionConfig(dict):
127
132
 
128
133
  def builtin_editable_fields(self):
129
134
  fields = ['participation_fee']
130
- if settings.USE_POINTS:
135
+ # Only show real_world_currency_per_point when using old currency system with points
136
+ if settings.CURRENCY_UNIT_CLASS is None and settings.USE_POINTS:
131
137
  fields.append('real_world_currency_per_point')
132
138
  return fields
133
139
 
@@ -53,6 +53,33 @@ def get_OTREE_APPS(SESSION_CONFIGS):
53
53
 
54
54
 
55
55
  OTREE_APPS = get_OTREE_APPS(settings.SESSION_CONFIGS)
56
+
57
+ # Handle CURRENCY_UNIT if defined
58
+ # Note: We don't import the class here to avoid circular imports
59
+ # The actual import happens in otree/main.py:setup()
60
+ CURRENCY_UNIT_CLASS = None
61
+ CURRENCY_UNIT_PATH = None
62
+ if hasattr(settings, 'CURRENCY_UNIT'):
63
+ # Check for incompatible old currency settings
64
+ old_currency_settings = [
65
+ 'USE_POINTS',
66
+ 'REAL_WORLD_CURRENCY_CODE',
67
+ 'POINTS_DECIMAL_PLACES',
68
+ 'POINTS_CUSTOM_NAME',
69
+ 'REAL_WORLD_CURRENCY_DECIMAL_PLACES',
70
+ ]
71
+ found_old_settings = [s for s in old_currency_settings if hasattr(settings, s)]
72
+ if found_old_settings:
73
+ msg = (
74
+ f"CURRENCY_UNIT is defined, but the following deprecated currency settings "
75
+ f"are also defined: {', '.join(found_old_settings)}. "
76
+ f"Please remove these settings when using CURRENCY_UNIT."
77
+ )
78
+ sys.exit(msg)
79
+
80
+ # Store the path for later import (done in main.py:setup() to avoid circular imports)
81
+ CURRENCY_UNIT_PATH = settings.CURRENCY_UNIT
82
+
56
83
  if not hasattr(settings, 'REAL_WORLD_CURRENCY_DECIMAL_PLACES'):
57
84
  if REAL_WORLD_CURRENCY_CODE in [
58
85
  'KRW',
@@ -45,10 +45,10 @@ function filterGroup(rowIdx) {
45
45
  let tbody = table.querySelector('tbody');
46
46
  let trs = tbody.querySelectorAll('tr');
47
47
 
48
- let curGroup = data[rowIdx][1]; // Group column is now at index 1
48
+ let curGroup = data[rowIdx][GROUP_COL_INDEX];
49
49
  let rowsInSameGroup = [];
50
50
  for (let i = 0; i < data.length; i++) {
51
- if (data[i][1] === curGroup) // Group column is now at index 1
51
+ if (data[i][GROUP_COL_INDEX] === curGroup)
52
52
  rowsInSameGroup.push(i);
53
53
  }
54
54
  for (let i = 0; i < trs.length; i++) {
@@ -71,8 +71,7 @@ function createTableRow(row, row_number) {
71
71
  for (let i = 0; i < row.length; i++) {
72
72
  let value = row[i];
73
73
  let td = document.createElement('td');
74
- if (i === 1) {
75
- // i === 1 is now the group column (participant.label is at i === 0)
74
+ if (i === GROUP_COL_INDEX) {
76
75
  td.innerHTML = `<a href="#" onclick="filterGroup(${row_number})">${value}</a>`;
77
76
  } else {
78
77
  td.innerHTML = makeCellDisplayValue(value);
@@ -106,7 +105,7 @@ function makeCellDisplayValue(value, fieldName) {
106
105
 
107
106
 
108
107
 
109
- function updateDataTable($table, new_json, old_json, field_headers) {
108
+ function updateDataTable($table, new_json, old_json, headers) {
110
109
  let changeDescriptions = [];
111
110
  let $tbody = $table.find('tbody');
112
111
  // build table for the first time
@@ -121,7 +120,8 @@ function updateDataTable($table, new_json, old_json, field_headers) {
121
120
  let new_value = makeCellDisplayValue(rawValue);
122
121
  $cell.text(new_value);
123
122
  flashGreen($cell);
124
- let fieldName = field_headers[j];
123
+ let header = headers[j];
124
+ let fieldName = header.prefix ? header.prefix + header.name : header.name;
125
125
  let newValueTrunc = truncateStringEllipsis(new_value, 7);
126
126
  rowChanges.push(`${fieldName}=${newValueTrunc}`);
127
127
  }
@@ -168,7 +168,8 @@
168
168
  let tables = document.getElementsByClassName('results-table');
169
169
  const round_numbers_by_subsession = {{ round_numbers_by_subsession|safe }};
170
170
  const app_names_by_subsession = {{ app_names_by_subsession|safe }};
171
- const FIELD_HEADERS = {{ field_headers_json|safe }};
171
+ const TABLE_HEADERS = {{ tables|safe }}.map(t => t.headers);
172
+ const GROUP_COL_INDEX = {{ GROUP_COL_INDEX }};
172
173
  let populatedTables = new Set(); // Track which tables have been populated
173
174
  $(document).ready(function () {
174
175
  $('#btn-refresh').click(function () {
@@ -267,8 +268,7 @@
267
268
  // REFRESH: Only update populated tables
268
269
  for (let tableIdx of populatedTables) {
269
270
  let table = tables[tableIdx];
270
- let appName = app_names_by_subsession[tableIdx];
271
- let headers = FIELD_HEADERS[appName];
271
+ let headers = TABLE_HEADERS[tableIdx];
272
272
  let data = new_json[tableIdx];
273
273
  changeDescriptions = changeDescriptions.concat(updateDataTable($(table), data, old_json[tableIdx], headers));
274
274
  }
@@ -313,7 +313,6 @@ class SessionData(AdminSessionPage):
313
313
  session = self.session
314
314
 
315
315
  tables = []
316
- field_headers = {}
317
316
  app_names_by_subsession = []
318
317
  round_numbers_by_subsession = []
319
318
  table_index = 0
@@ -323,7 +322,8 @@ class SessionData(AdminSessionPage):
323
322
  session=session
324
323
  ).count()
325
324
  pfields, gfields, sfields = export.get_fields_for_data_tab(app_name)
326
- field_headers[app_name] = pfields + gfields + sfields
325
+ # Remove id_in_subsession from gfields since we handle it separately
326
+ gfields = [f for f in gfields if f != 'id_in_subsession']
327
327
 
328
328
  for round_number in range(1, num_rounds + 1):
329
329
  # Build headers with indexes for sortability
@@ -331,7 +331,7 @@ class SessionData(AdminSessionPage):
331
331
  field_index = 0
332
332
 
333
333
  for field_name, prefix in [
334
- ('label', 'pp.'),
334
+ *[(col['display'], col['prefix']) for col in export.DATA_TAB_FIXED_COLUMNS],
335
335
  *[(f, '') for f in pfields],
336
336
  *[(f, 'group.') for f in gfields],
337
337
  *[(f, 'subsession.') for f in sfields],
@@ -353,9 +353,9 @@ class SessionData(AdminSessionPage):
353
353
  table_index += 1
354
354
  return dict(
355
355
  tables=tables,
356
- field_headers_json=json.dumps(field_headers),
357
356
  app_names_by_subsession=app_names_by_subsession,
358
357
  round_numbers_by_subsession=round_numbers_by_subsession,
358
+ GROUP_COL_INDEX=export.GROUP_COL_INDEX,
359
359
  DATA_EXPORT_HASH=otree.common.DATA_EXPORT_HASH,
360
360
  )
361
361
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: otree
3
- Version: 6.0.0b32
3
+ Version: 6.0.0b33
4
4
  Summary: Framework for multiplayer strategy games and complex surveys.
5
5
  Home-page: http://otree.org/
6
6
  Author: chris@otree.org
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes