swh.web 0.16.2__py3-none-any.whl → 0.16.4__py3-none-any.whl

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 (144) hide show
  1. swh/web/add_forge_now/templates/add-forge-request-dashboard.html +5 -2
  2. swh/web/api/views/origin.py +2 -2
  3. swh/web/archive_coverage/views.py +4 -7
  4. swh/web/badges/__init__.py +1 -1
  5. swh/web/badges/assets/index.js +40 -14
  6. swh/web/browse/assets/browse/browse.css +5 -0
  7. swh/web/browse/assets/browse/sidetabs.js +3 -16
  8. swh/web/browse/templates/browse-iframe.html +10 -7
  9. swh/web/browse/templates/browse-origin-visits.html +2 -2
  10. swh/web/browse/templates/browse-revision.html +5 -3
  11. swh/web/browse/templates/includes/content-display.html +10 -5
  12. swh/web/browse/templates/includes/readme-display.html +3 -2
  13. swh/web/browse/templates/includes/show-metadata.html +3 -2
  14. swh/web/browse/templates/includes/sidetabs.html +9 -7
  15. swh/web/browse/templates/includes/top-navigation.html +2 -1
  16. swh/web/browse/tests/views/test_origin.py +3 -1
  17. swh/web/deposit/templates/deposit-admin.html +6 -1
  18. swh/web/inbound_email/handle_message.py +1 -1
  19. swh/web/inbound_email/tests/test_utils.py +2 -2
  20. swh/web/save_code_now/assets/origin-save-admin.js +5 -2
  21. swh/web/save_code_now/assets/origin-save.js +9 -4
  22. swh/web/static/css/{archive_coverage.70eba3d32ed75472d638.css → archive_coverage.df54ae8fe40453ecd972.css} +2 -2
  23. swh/web/static/css/archive_coverage.df54ae8fe40453ecd972.css.map +1 -0
  24. swh/web/static/css/browse.633076034514e6a3977d.css +2 -0
  25. swh/web/static/css/browse.633076034514e6a3977d.css.map +1 -0
  26. swh/web/static/css/guided_tour.d496a0c252e1bb193496.css +2 -0
  27. swh/web/static/css/{guided_tour.62c03630e944b8b8d9ad.css.map → guided_tour.d496a0c252e1bb193496.css.map} +1 -1
  28. swh/web/static/css/{highlightjs.0c1b181eb006699a4c3e.css → highlightjs.37238c93749cb449800d.css} +2 -2
  29. swh/web/static/css/highlightjs.37238c93749cb449800d.css.map +1 -0
  30. swh/web/static/css/origin_visits.9a796c4df6606bd9905f.css +2 -0
  31. swh/web/static/css/origin_visits.9a796c4df6606bd9905f.css.map +1 -0
  32. swh/web/static/css/vendors.a4844da6ce54cbc04960.css +24 -0
  33. swh/web/static/css/vendors.a4844da6ce54cbc04960.css.map +1 -0
  34. swh/web/static/css/{webapp.4655323082740f1a4862.css → webapp.e995faa24f8c84db0d06.css} +2 -2
  35. swh/web/static/css/webapp.e995faa24f8c84db0d06.css.map +1 -0
  36. swh/web/static/js/add_forge_now.e85d09463e38c1e19632.js +3 -0
  37. swh/web/static/js/add_forge_now.e85d09463e38c1e19632.js.map +1 -0
  38. swh/web/static/js/auth.06c697ab58b81d08ebce.js +3 -0
  39. swh/web/static/js/auth.06c697ab58b81d08ebce.js.map +1 -0
  40. swh/web/static/js/badges.50941e27bf5e4453b0e0.js +3 -0
  41. swh/web/static/js/badges.50941e27bf5e4453b0e0.js.LICENSE.txt +6 -0
  42. swh/web/static/js/badges.50941e27bf5e4453b0e0.js.map +1 -0
  43. swh/web/static/js/browse.3f22819b69002c8b6407.js +3 -0
  44. swh/web/static/js/browse.3f22819b69002c8b6407.js.map +1 -0
  45. swh/web/static/js/deposit.d47e18177b16ccdbdb84.js.map +1 -1
  46. swh/web/static/js/{highlightjs.dc9b8354c69d942fad33.js → highlightjs.516e784a1e62011c7605.js} +3 -3
  47. swh/web/static/js/highlightjs.516e784a1e62011c7605.js.map +1 -0
  48. swh/web/static/js/mailmap.de04f685e56eff5b627f.js +3 -0
  49. swh/web/static/js/mailmap.de04f685e56eff5b627f.js.map +1 -0
  50. swh/web/static/js/mathjax.98ef576f318f1a0b0c4a.js.map +1 -1
  51. swh/web/static/js/pdf.worker.min.js +1 -1
  52. swh/web/static/js/pdfjs.018d9890c044b3612ece.js +3 -0
  53. swh/web/static/js/pdfjs.018d9890c044b3612ece.js.map +1 -0
  54. swh/web/static/js/{revision.ac9293e1b984b4d4d909.js → revision.122a31614a5f9abffc3c.js} +3 -3
  55. swh/web/static/js/revision.122a31614a5f9abffc3c.js.map +1 -0
  56. swh/web/static/js/save_code_now.d4d8fc47420a4badb683.js +3 -0
  57. swh/web/static/js/save_code_now.d4d8fc47420a4badb683.js.map +1 -0
  58. swh/web/static/js/vault.d2ec3dd1d84a8d038a6c.js +3 -0
  59. swh/web/static/js/vault.d2ec3dd1d84a8d038a6c.js.map +1 -0
  60. swh/web/static/js/vendors.f62cb86cf3b92ae280ee.js +3 -0
  61. swh/web/static/js/{vendors.2eeadf2e0831a7a82b6d.js.LICENSE.txt → vendors.f62cb86cf3b92ae280ee.js.LICENSE.txt} +5 -1
  62. swh/web/static/js/vendors.f62cb86cf3b92ae280ee.js.map +1 -0
  63. swh/web/static/js/webapp.e93873983e400db67bf8.js +3 -0
  64. swh/web/static/js/{webapp.26efc059a8f5fe204240.js.LICENSE.txt → webapp.e93873983e400db67bf8.js.LICENSE.txt} +1 -1
  65. swh/web/static/js/webapp.e93873983e400db67bf8.js.map +1 -0
  66. swh/web/static/jssources/@myriaddreamin/highlighter-typst/dist/esm/contrib/hljs/typst-lite.bundle.js +180 -111
  67. swh/web/static/jssources/assets/src/utils/functions.js +5 -5
  68. swh/web/static/jssources/core-js/LICENSE.txt +1 -1
  69. swh/web/static/jssources/core-js/internals/shared-store.js +3 -3
  70. swh/web/static/jssources/core-js/modules/es.object.group-by.js +2 -1
  71. swh/web/static/jssources/datatables.net/js/dataTables.mjs +108 -44
  72. swh/web/static/jssources/datatables.net-fixedheader/js/dataTables.fixedHeader.mjs +10 -4
  73. swh/web/static/jssources/datatables.net-fixedheader/node_modules/datatables.net/js/dataTables.mjs +14027 -0
  74. swh/web/static/jssources/datatables.net-fixedheader-bs5/node_modules/datatables.net/js/dataTables.mjs +14027 -0
  75. swh/web/static/jssources/datatables.net-fixedheader-bs5/node_modules/datatables.net-bs5/js/dataTables.bootstrap5.mjs +81 -0
  76. swh/web/static/jssources/dompurify/dist/purify.es.mjs +35 -12
  77. swh/web/static/jssources/highlightjs-line-numbers.js/src/highlightjs-line-numbers.js +1 -1
  78. swh/web/static/jssources/highlightjs-macaulay2/dist/macaulay2.min.js +3 -3
  79. swh/web/static/jssources/jslicenses.json +1 -1
  80. swh/web/static/jssources/pdfjs-dist/build/pdf.worker.mjs +885 -596
  81. swh/web/static/jssources/pdfjs-dist/legacy/build/pdf.mjs +4982 -4566
  82. swh/web/static/jssources/swh/web/badges/assets/index.js +40 -14
  83. swh/web/static/jssources/swh/web/browse/assets/browse/sidetabs.js +3 -16
  84. swh/web/static/jssources/swh/web/save_code_now/assets/origin-save-admin.js +5 -2
  85. swh/web/static/jssources/swh/web/save_code_now/assets/origin-save.js +9 -4
  86. swh/web/static/jssources/swh/web/vault/assets/vault-ui.js +6 -4
  87. swh/web/static/jssources/swh/web/webapp/assets/webapp/webapp-utils.js +18 -1
  88. swh/web/static/security.txt +3 -0
  89. swh/web/static/webpack-stats.json +240 -235
  90. swh/web/tests/views.py +9 -8
  91. swh/web/utils/archive.py +1 -1
  92. swh/web/utils/swh_templatetags.py +8 -13
  93. swh/web/vault/assets/vault-ui.js +6 -4
  94. swh/web/webapp/assets/webapp/webapp-utils.js +18 -1
  95. swh/web/webapp/assets/webapp/webapp.css +8 -0
  96. swh/web/webapp/templates/layout.html +13 -10
  97. swh/web/webapp/tests/test_views.py +16 -1
  98. {swh_web-0.16.2.dist-info → swh_web-0.16.4.dist-info}/METADATA +2 -3
  99. {swh_web-0.16.2.dist-info → swh_web-0.16.4.dist-info}/RECORD +112 -107
  100. swh/web/static/css/archive_coverage.70eba3d32ed75472d638.css.map +0 -1
  101. swh/web/static/css/browse.0a250d3b07ce628588a5.css +0 -2
  102. swh/web/static/css/browse.0a250d3b07ce628588a5.css.map +0 -1
  103. swh/web/static/css/guided_tour.62c03630e944b8b8d9ad.css +0 -2
  104. swh/web/static/css/highlightjs.0c1b181eb006699a4c3e.css.map +0 -1
  105. swh/web/static/css/origin_visits.88099d68a63f86af2f8e.css +0 -2
  106. swh/web/static/css/origin_visits.88099d68a63f86af2f8e.css.map +0 -1
  107. swh/web/static/css/vendors.1cfc8080eed63af482cf.css +0 -24
  108. swh/web/static/css/vendors.1cfc8080eed63af482cf.css.map +0 -1
  109. swh/web/static/css/webapp.4655323082740f1a4862.css.map +0 -1
  110. swh/web/static/js/add_forge_now.e25d1ad2ab6c45e60b67.js +0 -3
  111. swh/web/static/js/add_forge_now.e25d1ad2ab6c45e60b67.js.map +0 -1
  112. swh/web/static/js/auth.bd2f475f49caa9f84e99.js +0 -3
  113. swh/web/static/js/auth.bd2f475f49caa9f84e99.js.map +0 -1
  114. swh/web/static/js/badges.f02607179ad0264e7522.js +0 -2
  115. swh/web/static/js/badges.f02607179ad0264e7522.js.map +0 -1
  116. swh/web/static/js/browse.fc5d5fafca71e03d2add.js +0 -3
  117. swh/web/static/js/browse.fc5d5fafca71e03d2add.js.map +0 -1
  118. swh/web/static/js/highlightjs.dc9b8354c69d942fad33.js.map +0 -1
  119. swh/web/static/js/mailmap.631c53127ba5511ebda7.js +0 -3
  120. swh/web/static/js/mailmap.631c53127ba5511ebda7.js.map +0 -1
  121. swh/web/static/js/pdfjs.40675676ebcbdde8baab.js +0 -3
  122. swh/web/static/js/pdfjs.40675676ebcbdde8baab.js.map +0 -1
  123. swh/web/static/js/revision.ac9293e1b984b4d4d909.js.map +0 -1
  124. swh/web/static/js/save_code_now.369ff7f28aaf74e7728e.js +0 -3
  125. swh/web/static/js/save_code_now.369ff7f28aaf74e7728e.js.map +0 -1
  126. swh/web/static/js/vault.1229427aed95c78d4ee2.js +0 -3
  127. swh/web/static/js/vault.1229427aed95c78d4ee2.js.map +0 -1
  128. swh/web/static/js/vendors.2eeadf2e0831a7a82b6d.js +0 -3
  129. swh/web/static/js/vendors.2eeadf2e0831a7a82b6d.js.map +0 -1
  130. swh/web/static/js/webapp.26efc059a8f5fe204240.js +0 -3
  131. swh/web/static/js/webapp.26efc059a8f5fe204240.js.map +0 -1
  132. /swh/web/static/js/{add_forge_now.e25d1ad2ab6c45e60b67.js.LICENSE.txt → add_forge_now.e85d09463e38c1e19632.js.LICENSE.txt} +0 -0
  133. /swh/web/static/js/{auth.bd2f475f49caa9f84e99.js.LICENSE.txt → auth.06c697ab58b81d08ebce.js.LICENSE.txt} +0 -0
  134. /swh/web/static/js/{browse.fc5d5fafca71e03d2add.js.LICENSE.txt → browse.3f22819b69002c8b6407.js.LICENSE.txt} +0 -0
  135. /swh/web/static/js/{highlightjs.dc9b8354c69d942fad33.js.LICENSE.txt → highlightjs.516e784a1e62011c7605.js.LICENSE.txt} +0 -0
  136. /swh/web/static/js/{mailmap.631c53127ba5511ebda7.js.LICENSE.txt → mailmap.de04f685e56eff5b627f.js.LICENSE.txt} +0 -0
  137. /swh/web/static/js/{pdfjs.40675676ebcbdde8baab.js.LICENSE.txt → pdfjs.018d9890c044b3612ece.js.LICENSE.txt} +0 -0
  138. /swh/web/static/js/{revision.ac9293e1b984b4d4d909.js.LICENSE.txt → revision.122a31614a5f9abffc3c.js.LICENSE.txt} +0 -0
  139. /swh/web/static/js/{save_code_now.369ff7f28aaf74e7728e.js.LICENSE.txt → save_code_now.d4d8fc47420a4badb683.js.LICENSE.txt} +0 -0
  140. /swh/web/static/js/{vault.1229427aed95c78d4ee2.js.LICENSE.txt → vault.d2ec3dd1d84a8d038a6c.js.LICENSE.txt} +0 -0
  141. {swh_web-0.16.2.dist-info → swh_web-0.16.4.dist-info}/WHEEL +0 -0
  142. {swh_web-0.16.2.dist-info → swh_web-0.16.4.dist-info}/licenses/AUTHORS +0 -0
  143. {swh_web-0.16.2.dist-info → swh_web-0.16.4.dist-info}/licenses/LICENSE +0 -0
  144. {swh_web-0.16.2.dist-info → swh_web-0.16.4.dist-info}/top_level.txt +0 -0
swh/web/tests/views.py CHANGED
@@ -39,7 +39,7 @@ _content_code_data_filenames: Dict[str, Dict[str, str]] = {}
39
39
  _content_other_data_exts: Dict[str, Dict[str, str]] = {}
40
40
 
41
41
 
42
- def _init_content_tests_data(data_path, data_dict, ext_key):
42
+ def _init_content_tests_data(data_path, ext_key):
43
43
  """
44
44
  Helper function to read the content of a directory, store it
45
45
  into a test archive and add some files metadata (sha1 and/or
@@ -48,7 +48,6 @@ def _init_content_tests_data(data_path, data_dict, ext_key):
48
48
  Args:
49
49
  data_path (str): path to a directory relative to the tests
50
50
  folder of swh-web
51
- data_dict (dict): the dict that will store files metadata
52
51
  ext_key (bool): whether to use file extensions or filenames
53
52
  as dict keys
54
53
  """
@@ -60,6 +59,7 @@ def _init_content_tests_data(data_path, data_dict, ext_key):
60
59
  max_content_length=None,
61
60
  )
62
61
 
62
+ data_dict = {}
63
63
  contents = []
64
64
  for name, obj in directory.items():
65
65
  if obj.object_type == "content":
@@ -78,6 +78,7 @@ def _init_content_tests_data(data_path, data_dict, ext_key):
78
78
 
79
79
  storage = get_tests_data()["storage"]
80
80
  storage.content_add(contents)
81
+ return data_dict
81
82
 
82
83
 
83
84
  def _init_content_code_data_exts():
@@ -87,8 +88,8 @@ def _init_content_code_data_exts():
87
88
  """
88
89
  global _content_code_data_exts
89
90
  if not _content_code_data_exts:
90
- _init_content_tests_data(
91
- "resources/contents/code/extensions", _content_code_data_exts, True
91
+ _content_code_data_exts = _init_content_tests_data(
92
+ "resources/contents/code/extensions", True
92
93
  )
93
94
 
94
95
 
@@ -99,8 +100,8 @@ def _init_content_other_data_exts():
99
100
  """
100
101
  global _content_other_data_exts
101
102
  if not _content_other_data_exts:
102
- _init_content_tests_data(
103
- "resources/contents/other/extensions", _content_other_data_exts, True
103
+ _content_other_data_exts = _init_content_tests_data(
104
+ "resources/contents/other/extensions", True
104
105
  )
105
106
 
106
107
 
@@ -111,8 +112,8 @@ def _init_content_code_data_filenames():
111
112
  """
112
113
  global _content_code_data_filenames
113
114
  if not _content_code_data_filenames:
114
- _init_content_tests_data(
115
- "resources/contents/code/filenames", _content_code_data_filenames, False
115
+ _content_code_data_filenames = _init_content_tests_data(
116
+ "resources/contents/code/filenames", False
116
117
  )
117
118
 
118
119
 
swh/web/utils/archive.py CHANGED
@@ -1523,7 +1523,7 @@ def lookup_snapshot(
1523
1523
  A dict filled with the snapshot content.
1524
1524
  """
1525
1525
  snapshot_id_bin = _to_sha1_bin(snapshot_id)
1526
- if config.storage().snapshot_missing([snapshot_id_bin]):
1526
+ if list(config.storage().snapshot_missing([snapshot_id_bin])):
1527
1527
  raise NotFoundExc(f"Snapshot with id {snapshot_id} not found!")
1528
1528
 
1529
1529
  partial_branches = config.storage().snapshot_get_branches(
@@ -3,13 +3,12 @@
3
3
  # License: GNU Affero General Public License version 3, or any later version
4
4
  # See top-level LICENSE file for more information
5
5
 
6
- import json
7
6
  import re
8
7
  from typing import Optional
9
8
 
10
9
  from django import template
11
10
  from django.contrib.staticfiles.finders import find
12
- from django.utils.safestring import mark_safe
11
+ from django.utils.html import json_script
13
12
 
14
13
  from swh.web.save_code_now.origin_save import get_savable_visit_types
15
14
  from swh.web.utils import rst_to_html
@@ -72,19 +71,15 @@ def urlize_header_links(text):
72
71
  return ret[:-1]
73
72
 
74
73
 
75
- @register.filter
76
- def jsonify(obj):
77
- """Utility function for converting a django template variable
78
- to JSON in order to use it in script tags.
79
-
80
- Args
81
- obj: Any django template context variable
82
-
83
- Returns:
84
- JSON representation of the variable.
74
+ @register.filter(safe=True)
75
+ def swh_json_script(value, element_id):
76
+ """Safely outputs a Python object as JSON, wrapped in a <script> tag,
77
+ ready for use with JavaScript.
85
78
 
79
+ Same as ``json_script`` template filter from django but using a custom
80
+ JSON encoder.
86
81
  """
87
- return mark_safe(json.dumps(obj, cls=SWHDjangoJSONEncoder))
82
+ return json_script(value, element_id, encoder=SWHDjangoJSONEncoder)
88
83
 
89
84
 
90
85
  @register.filter
@@ -181,15 +181,17 @@ async function checkVaultCookingTasks() {
181
181
  });
182
182
  try {
183
183
  const responses = await Promise.all(cookingTaskRequests);
184
- handleFetchErrors(responses);
184
+ handleFetchErrors(responses, [404]);
185
185
  const cookingTasks = await Promise.all(responses.map(r => r.json()));
186
186
 
187
187
  const table = $('#vault-cooking-tasks tbody');
188
188
  for (let i = 0; i < cookingTasks.length; ++i) {
189
189
  const cookingTask = tasks[cookingTasks[i].swhid];
190
- cookingTask.status = cookingTasks[i].status;
191
- cookingTask.fetch_url = cookingTasks[i].fetch_url;
192
- cookingTask.progress_message = cookingTasks[i].progress_message;
190
+ if (cookingTask) {
191
+ cookingTask.status = cookingTasks[i].status;
192
+ cookingTask.fetch_url = cookingTasks[i].fetch_url;
193
+ cookingTask.progress_message = cookingTasks[i].progress_message;
194
+ }
193
195
  }
194
196
  for (let i = 0; i < vaultCookingTasks.length; ++i) {
195
197
  const cookingTask = vaultCookingTasks[i];
@@ -1,5 +1,5 @@
1
1
  /**
2
- * Copyright (C) 2018-2024 The Software Heritage developers
2
+ * Copyright (C) 2018-2025 The Software Heritage developers
3
3
  * See the AUTHORS file at the top-level directory of this distribution
4
4
  * License: GNU Affero General Public License version 3, or any later version
5
5
  * See top-level LICENSE file for more information
@@ -399,3 +399,20 @@ export function mirrorConfig() {
399
399
  export function resizeIframe() {
400
400
  return iframeResize.apply(null, arguments)[0].iframeResizer;
401
401
  }
402
+
403
+ export function parseJsonScript(scriptElementId) {
404
+ return JSON.parse($(`#${scriptElementId}`).text());
405
+ }
406
+
407
+ export function toggleButtonText(button, text) {
408
+ const currentLabel = button.innerHTML;
409
+
410
+ if (currentLabel === text) {
411
+ return;
412
+ }
413
+
414
+ button.innerHTML = text;
415
+ setTimeout(function() {
416
+ button.innerHTML = currentLabel;
417
+ }, 1000);
418
+ };
@@ -18,6 +18,14 @@ body {
18
18
  overflow-y: clip;
19
19
  }
20
20
 
21
+ /* Prevent scrolling of background when modal is opened */
22
+ body.modal-open {
23
+ overflow: hidden;
24
+ position: fixed;
25
+ width: 100%;
26
+ }
27
+
28
+
21
29
  /* The Alegreya font used in swh-web ships some ligatures producing
22
30
  confusing text rendering, for instance the ligatures for `~` and some
23
31
  characters like e, y, u, ... so disable font common ligatures */
@@ -56,9 +56,9 @@ along with this program. If not, see <https://www.gnu.org/licenses />.
56
56
  @licend The above is the entire license notice for the JavaScript code in this page.
57
57
  */
58
58
  </script>
59
- <script>SWH_CONFIG = {{swh_client_config|jsonify}};</script>
60
59
  <script src="{% url 'js-reverse' %}" type="text/javascript"></script>
61
- <script>swh.webapp.setSwhObjectIcons({{ swh_object_icons|jsonify }});</script>
60
+ {{ swh_object_icons|swh_json_script:"swh_object_icons" }}
61
+ <script>swh.webapp.setSwhObjectIcons(swh.webapp.parseJsonScript('swh_object_icons'));</script>
62
62
  {{ request.user.is_authenticated|json_script:"swh_user_logged_in" }}
63
63
  {{ request.user.is_staff|json_script:"swh_user_is_staff" }}
64
64
  {{ user_is_ambassador|json_script:"swh_user_is_ambassador" }}
@@ -187,13 +187,16 @@ along with this program. If not, see <https://www.gnu.org/licenses />.
187
187
  </main>
188
188
  {% include "./includes/footer.html" %}
189
189
  </div>
190
- <script>
191
- swh.webapp.setContainerFullWidth();
192
- {% if "server_url" in status and "json_path" in status %}
193
- var statusServerURL = {{ status.server_url|jsonify }};
194
- var statusJsonPath = {{ status.json_path|jsonify }};
195
- swh.webapp.initStatusWidget(statusServerURL + statusJsonPath);
196
- {% endif %}
197
- </script>
190
+ {% if "server_url" in status and "json_path" in status %}
191
+ {{ status.server_url|swh_json_script:"status_server_url" }}
192
+ {{ status.json_path|swh_json_script:"status_json_path" }}
193
+ <script>
194
+ swh.webapp.setContainerFullWidth();
195
+ swh.webapp.initStatusWidget(
196
+ swh.webapp.parseJsonScript('status_server_url') +
197
+ swh.webapp.parseJsonScript('status_json_path')
198
+ );
199
+ </script>
200
+ {% endif %}
198
201
  </body>
199
202
  </html>
@@ -1,9 +1,12 @@
1
- # Copyright (C) 2022 The Software Heritage developers
1
+ # Copyright (C) 2022-2025 The Software Heritage developers
2
2
  # See the AUTHORS file at the top-level directory of this distribution
3
3
  # License: GNU Affero General Public License version 3, or any later version
4
4
  # See top-level LICENSE file for more information
5
+ from datetime import datetime
6
+ from pathlib import Path
5
7
 
6
8
  from django.templatetags.static import static
9
+ from django.utils import timezone
7
10
 
8
11
  from swh.web.tests.helpers import check_html_get_response, check_http_get_response
9
12
  from swh.web.utils import reverse
@@ -29,3 +32,15 @@ def test_favicon_view(client):
29
32
  url = reverse("favicon")
30
33
  resp = check_http_get_response(client, url, status_code=301)
31
34
  assert resp["location"] == static(SWH_FAVICON)
35
+
36
+
37
+ def test_securitytxt_static(settings):
38
+ security_txt = Path(settings.STATIC_DIR) / "security.txt"
39
+ # static/security.txt contains a static expiration date, this test will fail
40
+ # if it expires in less than 30 days so we can check the file content is still
41
+ # valid
42
+ expiration_date = datetime.fromisoformat(
43
+ security_txt.read_text().splitlines()[1].split(": ")[1]
44
+ )
45
+ delta = expiration_date - timezone.now()
46
+ assert delta.days > 30
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: swh.web
3
- Version: 0.16.2
3
+ Version: 0.16.4
4
4
  Summary: Software Heritage web UI
5
5
  Author-email: Software Heritage developers <swh-devel@inria.fr>
6
6
  Project-URL: Homepage, https://gitlab.softwareheritage.org/swh/devel/swh-web
@@ -37,7 +37,7 @@ Requires-Dist: looseversion
37
37
  Requires-Dist: msgpack
38
38
  Requires-Dist: prometheus-client
39
39
  Requires-Dist: psycopg
40
- Requires-Dist: pybadges>=2.2.1
40
+ Requires-Dist: pybadges2
41
41
  Requires-Dist: pygments
42
42
  Requires-Dist: pymemcache
43
43
  Requires-Dist: python-magic>=0.4.0
@@ -45,7 +45,6 @@ Requires-Dist: pyyaml
45
45
  Requires-Dist: requests
46
46
  Requires-Dist: rfc3987
47
47
  Requires-Dist: sentry-sdk
48
- Requires-Dist: standard-imghdr; python_version > "3.12"
49
48
  Requires-Dist: swh.auth[django]>=0.6.7
50
49
  Requires-Dist: swh.core>=4.0.0
51
50
  Requires-Dist: swh.counters>=0.5.1