psdi-data-conversion 0.0.38__tar.gz → 0.0.39__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 (141) hide show
  1. {psdi_data_conversion-0.0.38 → psdi_data_conversion-0.0.39}/PKG-INFO +1 -1
  2. {psdi_data_conversion-0.0.38 → psdi_data_conversion-0.0.39}/psdi_data_conversion/app.py +39 -15
  3. {psdi_data_conversion-0.0.38 → psdi_data_conversion-0.0.39}/psdi_data_conversion/converter.py +7 -7
  4. {psdi_data_conversion-0.0.38 → psdi_data_conversion-0.0.39}/psdi_data_conversion/converters/base.py +24 -20
  5. {psdi_data_conversion-0.0.38 → psdi_data_conversion-0.0.39}/psdi_data_conversion/converters/c2x.py +13 -0
  6. {psdi_data_conversion-0.0.38 → psdi_data_conversion-0.0.39}/psdi_data_conversion/converters/openbabel.py +2 -1
  7. {psdi_data_conversion-0.0.38 → psdi_data_conversion-0.0.39}/psdi_data_conversion/database.py +29 -5
  8. {psdi_data_conversion-0.0.38 → psdi_data_conversion-0.0.39}/psdi_data_conversion/dist.py +2 -1
  9. {psdi_data_conversion-0.0.38 → psdi_data_conversion-0.0.39}/psdi_data_conversion/file_io.py +1 -2
  10. {psdi_data_conversion-0.0.38 → psdi_data_conversion-0.0.39}/psdi_data_conversion/main.py +3 -3
  11. {psdi_data_conversion-0.0.38 → psdi_data_conversion-0.0.39}/psdi_data_conversion/static/content/index-versions/psdi-common-footer.html +12 -8
  12. {psdi_data_conversion-0.0.38 → psdi_data_conversion-0.0.39}/psdi_data_conversion/static/content/psdi-common-footer.html +12 -8
  13. {psdi_data_conversion-0.0.38 → psdi_data_conversion-0.0.39}/psdi_data_conversion/static/data/data.json +617 -3
  14. {psdi_data_conversion-0.0.38 → psdi_data_conversion-0.0.39}/psdi_data_conversion/static/javascript/convert.js +54 -6
  15. {psdi_data_conversion-0.0.38 → psdi_data_conversion-0.0.39}/psdi_data_conversion/static/javascript/convert_common.js +16 -2
  16. {psdi_data_conversion-0.0.38 → psdi_data_conversion-0.0.39}/psdi_data_conversion/static/javascript/data.js +18 -0
  17. {psdi_data_conversion-0.0.38 → psdi_data_conversion-0.0.39}/psdi_data_conversion/static/styles/format.css +7 -0
  18. {psdi_data_conversion-0.0.38 → psdi_data_conversion-0.0.39}/psdi_data_conversion/testing/conversion_test_specs.py +17 -5
  19. {psdi_data_conversion-0.0.38 → psdi_data_conversion-0.0.39}/psdi_data_conversion/testing/gui.py +18 -12
  20. {psdi_data_conversion-0.0.38 → psdi_data_conversion-0.0.39}/tests/gui/gui_test.py +3 -2
  21. {psdi_data_conversion-0.0.38 → psdi_data_conversion-0.0.39}/tests/python/cli_test.py +7 -6
  22. {psdi_data_conversion-0.0.38 → psdi_data_conversion-0.0.39}/.gitignore +0 -0
  23. {psdi_data_conversion-0.0.38 → psdi_data_conversion-0.0.39}/CHANGELOG.md +0 -0
  24. {psdi_data_conversion-0.0.38 → psdi_data_conversion-0.0.39}/CONTRIBUTING.md +0 -0
  25. {psdi_data_conversion-0.0.38 → psdi_data_conversion-0.0.39}/LICENSE +0 -0
  26. {psdi_data_conversion-0.0.38 → psdi_data_conversion-0.0.39}/README.md +0 -0
  27. {psdi_data_conversion-0.0.38 → psdi_data_conversion-0.0.39}/psdi_data_conversion/__init__.py +0 -0
  28. {psdi_data_conversion-0.0.38 → psdi_data_conversion-0.0.39}/psdi_data_conversion/bin/LICENSE_ATOMSK +0 -0
  29. {psdi_data_conversion-0.0.38 → psdi_data_conversion-0.0.39}/psdi_data_conversion/bin/LICENSE_C2X +0 -0
  30. {psdi_data_conversion-0.0.38 → psdi_data_conversion-0.0.39}/psdi_data_conversion/bin/linux/atomsk +0 -0
  31. {psdi_data_conversion-0.0.38 → psdi_data_conversion-0.0.39}/psdi_data_conversion/bin/linux/c2x +0 -0
  32. {psdi_data_conversion-0.0.38 → psdi_data_conversion-0.0.39}/psdi_data_conversion/bin/mac/atomsk +0 -0
  33. {psdi_data_conversion-0.0.38 → psdi_data_conversion-0.0.39}/psdi_data_conversion/bin/mac/c2x +0 -0
  34. {psdi_data_conversion-0.0.38 → psdi_data_conversion-0.0.39}/psdi_data_conversion/constants.py +0 -0
  35. {psdi_data_conversion-0.0.38 → psdi_data_conversion-0.0.39}/psdi_data_conversion/converters/__init__.py +0 -0
  36. {psdi_data_conversion-0.0.38 → psdi_data_conversion-0.0.39}/psdi_data_conversion/converters/atomsk.py +0 -0
  37. {psdi_data_conversion-0.0.38 → psdi_data_conversion-0.0.39}/psdi_data_conversion/log_utility.py +1 -1
  38. {psdi_data_conversion-0.0.38 → psdi_data_conversion-0.0.39}/psdi_data_conversion/scripts/atomsk.sh +0 -0
  39. {psdi_data_conversion-0.0.38 → psdi_data_conversion-0.0.39}/psdi_data_conversion/scripts/c2x.sh +0 -0
  40. {psdi_data_conversion-0.0.38 → psdi_data_conversion-0.0.39}/psdi_data_conversion/security.py +0 -0
  41. {psdi_data_conversion-0.0.38 → psdi_data_conversion-0.0.39}/psdi_data_conversion/static/content/accessibility.htm +0 -0
  42. {psdi_data_conversion-0.0.38 → psdi_data_conversion-0.0.39}/psdi_data_conversion/static/content/convert.htm +0 -0
  43. {psdi_data_conversion-0.0.38 → psdi_data_conversion-0.0.39}/psdi_data_conversion/static/content/convertato.htm +0 -0
  44. {psdi_data_conversion-0.0.38 → psdi_data_conversion-0.0.39}/psdi_data_conversion/static/content/convertc2x.htm +0 -0
  45. {psdi_data_conversion-0.0.38 → psdi_data_conversion-0.0.39}/psdi_data_conversion/static/content/documentation.htm +0 -0
  46. {psdi_data_conversion-0.0.38 → psdi_data_conversion-0.0.39}/psdi_data_conversion/static/content/download.htm +0 -0
  47. {psdi_data_conversion-0.0.38 → psdi_data_conversion-0.0.39}/psdi_data_conversion/static/content/feedback.htm +0 -0
  48. {psdi_data_conversion-0.0.38 → psdi_data_conversion-0.0.39}/psdi_data_conversion/static/content/header-links.html +0 -0
  49. {psdi_data_conversion-0.0.38 → psdi_data_conversion-0.0.39}/psdi_data_conversion/static/content/index-versions/header-links.html +0 -0
  50. {psdi_data_conversion-0.0.38 → psdi_data_conversion-0.0.39}/psdi_data_conversion/static/content/index-versions/psdi-common-header.html +0 -0
  51. {psdi_data_conversion-0.0.38 → psdi_data_conversion-0.0.39}/psdi_data_conversion/static/content/psdi-common-header.html +0 -0
  52. {psdi_data_conversion-0.0.38 → psdi_data_conversion-0.0.39}/psdi_data_conversion/static/content/report.htm +0 -0
  53. {psdi_data_conversion-0.0.38 → psdi_data_conversion-0.0.39}/psdi_data_conversion/static/img/colormode-toggle-dm.svg +0 -0
  54. {psdi_data_conversion-0.0.38 → psdi_data_conversion-0.0.39}/psdi_data_conversion/static/img/colormode-toggle-lm.svg +0 -0
  55. {psdi_data_conversion-0.0.38 → psdi_data_conversion-0.0.39}/psdi_data_conversion/static/img/psdi-icon-dark.svg +0 -0
  56. {psdi_data_conversion-0.0.38 → psdi_data_conversion-0.0.39}/psdi_data_conversion/static/img/psdi-icon-light.svg +0 -0
  57. {psdi_data_conversion-0.0.38 → psdi_data_conversion-0.0.39}/psdi_data_conversion/static/img/psdi-logo-darktext-simple.png +0 -0
  58. {psdi_data_conversion-0.0.38 → psdi_data_conversion-0.0.39}/psdi_data_conversion/static/img/psdi-logo-darktext.png +0 -0
  59. {psdi_data_conversion-0.0.38 → psdi_data_conversion-0.0.39}/psdi_data_conversion/static/img/psdi-logo-lighttext-simple.png +0 -0
  60. {psdi_data_conversion-0.0.38 → psdi_data_conversion-0.0.39}/psdi_data_conversion/static/img/psdi-logo-lighttext.png +0 -0
  61. {psdi_data_conversion-0.0.38 → psdi_data_conversion-0.0.39}/psdi_data_conversion/static/img/social-logo-bluesky-black.svg +0 -0
  62. {psdi_data_conversion-0.0.38 → psdi_data_conversion-0.0.39}/psdi_data_conversion/static/img/social-logo-bluesky-white.svg +0 -0
  63. {psdi_data_conversion-0.0.38 → psdi_data_conversion-0.0.39}/psdi_data_conversion/static/img/social-logo-instagram-black.svg +0 -0
  64. {psdi_data_conversion-0.0.38 → psdi_data_conversion-0.0.39}/psdi_data_conversion/static/img/social-logo-instagram-white.svg +0 -0
  65. {psdi_data_conversion-0.0.38 → psdi_data_conversion-0.0.39}/psdi_data_conversion/static/img/social-logo-linkedin-black.png +0 -0
  66. {psdi_data_conversion-0.0.38 → psdi_data_conversion-0.0.39}/psdi_data_conversion/static/img/social-logo-linkedin-white.png +0 -0
  67. {psdi_data_conversion-0.0.38 → psdi_data_conversion-0.0.39}/psdi_data_conversion/static/img/social-logo-mastodon-black.svg +0 -0
  68. {psdi_data_conversion-0.0.38 → psdi_data_conversion-0.0.39}/psdi_data_conversion/static/img/social-logo-mastodon-white.svg +0 -0
  69. {psdi_data_conversion-0.0.38 → psdi_data_conversion-0.0.39}/psdi_data_conversion/static/img/social-logo-x-black.svg +0 -0
  70. {psdi_data_conversion-0.0.38 → psdi_data_conversion-0.0.39}/psdi_data_conversion/static/img/social-logo-x-white.svg +0 -0
  71. {psdi_data_conversion-0.0.38 → psdi_data_conversion-0.0.39}/psdi_data_conversion/static/img/social-logo-youtube-black.png +0 -0
  72. {psdi_data_conversion-0.0.38 → psdi_data_conversion-0.0.39}/psdi_data_conversion/static/img/social-logo-youtube-white.png +0 -0
  73. {psdi_data_conversion-0.0.38 → psdi_data_conversion-0.0.39}/psdi_data_conversion/static/img/ukri-epsr-logo-darktext.png +0 -0
  74. {psdi_data_conversion-0.0.38 → psdi_data_conversion-0.0.39}/psdi_data_conversion/static/img/ukri-epsr-logo-lighttext.png +0 -0
  75. {psdi_data_conversion-0.0.38 → psdi_data_conversion-0.0.39}/psdi_data_conversion/static/img/ukri-logo-darktext.png +0 -0
  76. {psdi_data_conversion-0.0.38 → psdi_data_conversion-0.0.39}/psdi_data_conversion/static/img/ukri-logo-lighttext.png +0 -0
  77. {psdi_data_conversion-0.0.38 → psdi_data_conversion-0.0.39}/psdi_data_conversion/static/javascript/accessibility.js +0 -0
  78. {psdi_data_conversion-0.0.38 → psdi_data_conversion-0.0.39}/psdi_data_conversion/static/javascript/common.js +0 -0
  79. {psdi_data_conversion-0.0.38 → psdi_data_conversion-0.0.39}/psdi_data_conversion/static/javascript/convertato.js +0 -0
  80. {psdi_data_conversion-0.0.38 → psdi_data_conversion-0.0.39}/psdi_data_conversion/static/javascript/convertc2x.js +0 -0
  81. {psdi_data_conversion-0.0.38 → psdi_data_conversion-0.0.39}/psdi_data_conversion/static/javascript/format.js +0 -0
  82. {psdi_data_conversion-0.0.38 → psdi_data_conversion-0.0.39}/psdi_data_conversion/static/javascript/load_accessibility.js +0 -0
  83. {psdi_data_conversion-0.0.38 → psdi_data_conversion-0.0.39}/psdi_data_conversion/static/javascript/psdi-common.js +0 -0
  84. {psdi_data_conversion-0.0.38 → psdi_data_conversion-0.0.39}/psdi_data_conversion/static/javascript/report.js +0 -0
  85. {psdi_data_conversion-0.0.38 → psdi_data_conversion-0.0.39}/psdi_data_conversion/static/styles/psdi-common.css +0 -0
  86. {psdi_data_conversion-0.0.38 → psdi_data_conversion-0.0.39}/psdi_data_conversion/templates/index.htm +0 -0
  87. {psdi_data_conversion-0.0.38 → psdi_data_conversion-0.0.39}/psdi_data_conversion/testing/__init__.py +0 -0
  88. {psdi_data_conversion-0.0.38 → psdi_data_conversion-0.0.39}/psdi_data_conversion/testing/constants.py +0 -0
  89. {psdi_data_conversion-0.0.38 → psdi_data_conversion-0.0.39}/psdi_data_conversion/testing/conversion_callbacks.py +2 -2
  90. {psdi_data_conversion-0.0.38 → psdi_data_conversion-0.0.39}/psdi_data_conversion/testing/utils.py +3 -3
  91. {psdi_data_conversion-0.0.38 → psdi_data_conversion-0.0.39}/pyproject.toml +0 -0
  92. {psdi_data_conversion-0.0.38 → psdi_data_conversion-0.0.39}/scripts/setup_bin.py +0 -0
  93. {psdi_data_conversion-0.0.38 → psdi_data_conversion-0.0.39}/test_data/1ARJ.mmcif +0 -0
  94. {psdi_data_conversion-0.0.38 → psdi_data_conversion-0.0.39}/test_data/1NE6.mmcif +0 -0
  95. {psdi_data_conversion-0.0.38 → psdi_data_conversion-0.0.39}/test_data/5a9z-assembly1.cif +0 -0
  96. {psdi_data_conversion-0.0.38 → psdi_data_conversion-0.0.39}/test_data/Fapatite.ins +0 -0
  97. {psdi_data_conversion-0.0.38 → psdi_data_conversion-0.0.39}/test_data/aceticacid.mol +0 -0
  98. {psdi_data_conversion-0.0.38 → psdi_data_conversion-0.0.39}/test_data/benzyne.molden +0 -0
  99. {psdi_data_conversion-0.0.38 → psdi_data_conversion-0.0.39}/test_data/caffeine-smi.tar +0 -0
  100. {psdi_data_conversion-0.0.38 → psdi_data_conversion-0.0.39}/test_data/caffeine-smi.tar.gz +0 -0
  101. {psdi_data_conversion-0.0.38 → psdi_data_conversion-0.0.39}/test_data/caffeine-smi.zip +0 -0
  102. {psdi_data_conversion-0.0.38 → psdi_data_conversion-0.0.39}/test_data/caffeine.inchi +0 -0
  103. {psdi_data_conversion-0.0.38 → psdi_data_conversion-0.0.39}/test_data/ch3cl-esp.cub +0 -0
  104. {psdi_data_conversion-0.0.38 → psdi_data_conversion-0.0.39}/test_data/cyclopropane_err.mol +0 -0
  105. {psdi_data_conversion-0.0.38 → psdi_data_conversion-0.0.39}/test_data/ethanol.xyz +0 -0
  106. {psdi_data_conversion-0.0.38 → psdi_data_conversion-0.0.39}/test_data/fullRhinovirus.pdb +0 -0
  107. {psdi_data_conversion-0.0.38 → psdi_data_conversion-0.0.39}/test_data/hemoglobin.pdb +0 -0
  108. {psdi_data_conversion-0.0.38 → psdi_data_conversion-0.0.39}/test_data/nacl.cif +0 -0
  109. {psdi_data_conversion-0.0.38 → psdi_data_conversion-0.0.39}/test_data/nacl.mol +0 -0
  110. {psdi_data_conversion-0.0.38 → psdi_data_conversion-0.0.39}/test_data/output/aceticacid.log.txt +0 -0
  111. {psdi_data_conversion-0.0.38 → psdi_data_conversion-0.0.39}/test_data/output/aceticacid.mol2 +0 -0
  112. {psdi_data_conversion-0.0.38 → psdi_data_conversion-0.0.39}/test_data/output/caffeine-2D-fastest.xyz +0 -0
  113. {psdi_data_conversion-0.0.38 → psdi_data_conversion-0.0.39}/test_data/output/caffeine-3D-best.xyz +0 -0
  114. {psdi_data_conversion-0.0.38 → psdi_data_conversion-0.0.39}/test_data/output/caffeine.smi +0 -0
  115. {psdi_data_conversion-0.0.38 → psdi_data_conversion-0.0.39}/test_data/output/caffeine.xyz +0 -0
  116. {psdi_data_conversion-0.0.38 → psdi_data_conversion-0.0.39}/test_data/output/caffeine_a_in.smi +0 -0
  117. {psdi_data_conversion-0.0.38 → psdi_data_conversion-0.0.39}/test_data/output/caffeine_a_in_kx_f4_l5_out.smi +0 -0
  118. {psdi_data_conversion-0.0.38 → psdi_data_conversion-0.0.39}/test_data/output/caffeine_a_in_kx_f4_out.smi +0 -0
  119. {psdi_data_conversion-0.0.38 → psdi_data_conversion-0.0.39}/test_data/output/caffeine_a_in_kx_out.smi +0 -0
  120. {psdi_data_conversion-0.0.38 → psdi_data_conversion-0.0.39}/test_data/output/caffeine_a_in_x_out.smi +0 -0
  121. {psdi_data_conversion-0.0.38 → psdi_data_conversion-0.0.39}/test_data/output/hemoglobin_Atomsk.xyz +0 -0
  122. {psdi_data_conversion-0.0.38 → psdi_data_conversion-0.0.39}/test_data/output/hemoglobin_c2x.xyz +0 -0
  123. {psdi_data_conversion-0.0.38 → psdi_data_conversion-0.0.39}/test_data/output/nacl.log +0 -0
  124. {psdi_data_conversion-0.0.38 → psdi_data_conversion-0.0.39}/test_data/output/nacl.mol +0 -0
  125. {psdi_data_conversion-0.0.38 → psdi_data_conversion-0.0.39}/test_data/output/quartz_OB.cif +0 -0
  126. {psdi_data_conversion-0.0.38 → psdi_data_conversion-0.0.39}/test_data/output/quartz_OB.log.txt +0 -0
  127. {psdi_data_conversion-0.0.38 → psdi_data_conversion-0.0.39}/test_data/output/quartz_atomsk.cif +0 -0
  128. {psdi_data_conversion-0.0.38 → psdi_data_conversion-0.0.39}/test_data/output/quartz_atomsk.log.txt +0 -0
  129. {psdi_data_conversion-0.0.38 → psdi_data_conversion-0.0.39}/test_data/output/standard_test.inchi +0 -0
  130. {psdi_data_conversion-0.0.38 → psdi_data_conversion-0.0.39}/test_data/output/xyz_files-mol.zip +0 -0
  131. {psdi_data_conversion-0.0.38 → psdi_data_conversion-0.0.39}/test_data/output/xyz_files.log.txt +0 -0
  132. {psdi_data_conversion-0.0.38 → psdi_data_conversion-0.0.39}/test_data/periodic_dmol3.outmol +0 -0
  133. {psdi_data_conversion-0.0.38 → psdi_data_conversion-0.0.39}/test_data/quartz.xyz +0 -0
  134. {psdi_data_conversion-0.0.38 → psdi_data_conversion-0.0.39}/test_data/quartz_err.xyz +0 -0
  135. {psdi_data_conversion-0.0.38 → psdi_data_conversion-0.0.39}/test_data/standard_test.cdxml +0 -0
  136. {psdi_data_conversion-0.0.38 → psdi_data_conversion-0.0.39}/tests/python/converter_test.py +0 -0
  137. {psdi_data_conversion-0.0.38 → psdi_data_conversion-0.0.39}/tests/python/database_test.py +0 -0
  138. {psdi_data_conversion-0.0.38 → psdi_data_conversion-0.0.39}/tests/python/dist_test.py +0 -0
  139. {psdi_data_conversion-0.0.38 → psdi_data_conversion-0.0.39}/tests/python/file_io_test.py +0 -0
  140. {psdi_data_conversion-0.0.38 → psdi_data_conversion-0.0.39}/tests/python/logging_test.py +0 -0
  141. {psdi_data_conversion-0.0.38 → psdi_data_conversion-0.0.39}/tests/python/security_test.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: psdi_data_conversion
3
- Version: 0.0.38
3
+ Version: 0.0.39
4
4
  Summary: Chemistry file format conversion service, provided by PSDI
5
5
  Project-URL: Homepage, https://data-conversion.psdi.ac.uk/
6
6
  Project-URL: Documentation, https://psdi-uk.github.io/psdi-data-conversion/
@@ -5,22 +5,28 @@ Version 1.0, 8th November 2024
5
5
  This script acts as a server for the PSDI Data Conversion Service website.
6
6
  """
7
7
 
8
- from argparse import ArgumentParser
9
- import hashlib
10
- import os
11
8
  import json
9
+ import os
10
+ import sys
11
+ from argparse import ArgumentParser
12
+ from collections.abc import Callable
12
13
  from datetime import datetime
14
+ from functools import wraps
15
+ from hashlib import md5
13
16
  from subprocess import run
14
- import sys
15
- import traceback
16
- from flask import Flask, request, render_template, abort, Response
17
+ from traceback import format_exc
18
+ from typing import Any
19
+
20
+ import werkzeug.serving
21
+ from flask import Flask, Response, abort, cli, render_template, request
17
22
 
18
23
  import psdi_data_conversion
19
- from psdi_data_conversion import log_utility
20
24
  from psdi_data_conversion import constants as const
25
+ from psdi_data_conversion import log_utility
21
26
  from psdi_data_conversion.converter import run_converter
22
- from psdi_data_conversion.database import FormatInfo, get_format_info
27
+ from psdi_data_conversion.database import get_format_info
23
28
  from psdi_data_conversion.file_io import split_archive_ext
29
+ from psdi_data_conversion.main import print_wrap
24
30
 
25
31
  # Env var for the SHA of the latest commit
26
32
  SHA_EV = "SHA"
@@ -36,7 +42,7 @@ FILE_TO_UPLOAD_KEY = 'fileToUpload'
36
42
 
37
43
  # Create a token by hashing the current date and time.
38
44
  dt = str(datetime.now())
39
- token = hashlib.md5(dt.encode('utf8')).hexdigest()
45
+ token = md5(dt.encode('utf8')).hexdigest()
40
46
 
41
47
  # Get the service and production modes from their envvars
42
48
  service_mode_ev = os.environ.get(SERVICE_MODE_EV)
@@ -80,6 +86,22 @@ if ev_max_file_size_ob is not None:
80
86
  else:
81
87
  max_file_size_ob = const.DEFAULT_MAX_FILE_SIZE_OB
82
88
 
89
+ # Since we're using the development server as the user GUI, we monkey-patch Flask to disable the warnings that would
90
+ # otherwise appear for this so they don't confuse the user
91
+
92
+
93
+ def suppress_warning(func: Callable[..., Any]) -> Callable[..., Any]:
94
+ @wraps(func)
95
+ def wrapper(*args, **kwargs) -> Any:
96
+ if args and isinstance(args[0], str) and args[0].startswith('WARNING: This is a development server.'):
97
+ return ''
98
+ return func(*args, **kwargs)
99
+ return wrapper
100
+
101
+
102
+ werkzeug.serving._ansi_style = suppress_warning(werkzeug.serving._ansi_style)
103
+ cli.show_server_banner = lambda *_: None
104
+
83
105
  app = Flask(__name__)
84
106
 
85
107
 
@@ -101,7 +123,7 @@ def get_last_sha() -> str:
101
123
  out_str = str(out_bytes.decode()).strip()
102
124
 
103
125
  except Exception:
104
- print("ERROR: Could not determine SHA of most recent commit. Error was:\n" + traceback.format_exc(),
126
+ print("ERROR: Could not determine SHA of most recent commit. Error was:\n" + format_exc(),
105
127
  file=sys.stderr)
106
128
  out_str = "N/A"
107
129
 
@@ -146,7 +168,7 @@ def convert():
146
168
  name = request.form[format_label]
147
169
  full_note = request.form[format_label+"_full"]
148
170
 
149
- l_possible_formats: list[FormatInfo] = get_format_info(name, which="all")
171
+ l_possible_formats = get_format_info(name, which="all")
150
172
 
151
173
  # If there's only one possible format, use that
152
174
  if len(l_possible_formats) == 1:
@@ -154,13 +176,11 @@ def convert():
154
176
  continue
155
177
 
156
178
  # Otherwise, find the format with the matching note
157
- found = False
158
179
  for possible_format in l_possible_formats:
159
180
  if possible_format.note in full_note:
160
181
  d_formats[format_label] = possible_format
161
- found = True
162
182
  break
163
- if not found:
183
+ else:
164
184
  print(f"Format '{name}' with full description '{full_note}' could not be found in database.",
165
185
  file=sys.stderr)
166
186
  abort(const.STATUS_CODE_GENERAL)
@@ -200,7 +220,7 @@ def convert():
200
220
  else:
201
221
  # Failsafe exception message
202
222
  msg = ("The following unexpected exception was raised by the converter:\n" +
203
- traceback.format_exc()+"\n")
223
+ format_exc()+"\n")
204
224
  with open(qualified_output_log, "w") as fo:
205
225
  fo.write(msg)
206
226
  abort(status_code)
@@ -360,6 +380,10 @@ def main():
360
380
  global log_level
361
381
  log_level = args.log_level
362
382
 
383
+ print_wrap("Starting the PSDI Data Conversion GUI. This GUI is run as a webpage, which you can open by "
384
+ "right-clicking the link below to open it in your default browser, or by copy-and-pasting it into your "
385
+ "browser of choice.")
386
+
363
387
  start_app()
364
388
 
365
389
 
@@ -5,18 +5,18 @@ Created 2024-12-10 by Bryan Gillis.
5
5
  Class and functions to perform file conversion
6
6
  """
7
7
 
8
- from dataclasses import dataclass, field
9
- import os
8
+ import glob
10
9
  import importlib
10
+ import os
11
11
  import sys
12
- from tempfile import TemporaryDirectory
13
12
  import traceback
14
- from typing import Any, Callable, NamedTuple
13
+ from collections.abc import Callable
14
+ from dataclasses import dataclass, field
15
+ from tempfile import TemporaryDirectory
16
+ from typing import Any, NamedTuple
17
+
15
18
  from psdi_data_conversion import constants as const
16
19
  from psdi_data_conversion.converters import base
17
-
18
- import glob
19
-
20
20
  from psdi_data_conversion.converters.openbabel import CONVERTER_OB
21
21
  from psdi_data_conversion.file_io import (is_archive, is_supported_archive, pack_zip_or_tar, split_archive_ext,
22
22
  unpack_zip_or_tar)
@@ -6,19 +6,19 @@ Base class and information for file format converters
6
6
  """
7
7
 
8
8
 
9
- from copy import deepcopy
10
- from dataclasses import dataclass
9
+ import abc
11
10
  import logging
12
- from collections.abc import Callable
13
11
  import os
14
12
  import subprocess
15
- import abc
16
-
17
13
  import sys
18
14
  import traceback
15
+ from collections.abc import Callable
16
+ from copy import deepcopy
17
+ from dataclasses import dataclass
19
18
  from typing import Any
20
19
 
21
- from psdi_data_conversion import constants as const, log_utility
20
+ from psdi_data_conversion import constants as const
21
+ from psdi_data_conversion import log_utility
22
22
  from psdi_data_conversion.dist import bin_exists, get_bin_path, get_dist
23
23
  from psdi_data_conversion.security import SAFE_STRING_RE, string_is_safe
24
24
 
@@ -735,24 +735,11 @@ class ScriptFileConverter(FileConverter):
735
735
 
736
736
  self.logger.debug(f"Performing conversion with ScriptFileConverter using script '{self.script}'")
737
737
 
738
- from_flags = self.data.get("from_flags", "")
739
- to_flags = self.data.get("from_flags", "")
740
- from_options = self.data.get("from_options", "")
741
- to_options = self.data.get("from_options", "")
742
-
743
- # Check that all user-provided input passes security checks
744
- for user_args in [from_flags, to_flags, from_options, to_options]:
745
- if not string_is_safe(user_args):
746
- raise FileConverterInputException(f"Provided argument '{user_args}' does not pass security check - it "
747
- f"must match the regex {SAFE_STRING_RE.pattern}.", help=True)
748
-
749
738
  env = {"DIST": get_dist()}
750
739
  if self.required_bin is not None:
751
740
  env["BIN_PATH"] = get_bin_path(self.required_bin)
752
741
 
753
- process = subprocess.run(['sh', f'psdi_data_conversion/scripts/{self.script}',
754
- '--' + self.to_format_info.name, self.in_filename, self.out_filename, from_flags,
755
- to_flags, from_options, to_options],
742
+ process = subprocess.run(['sh', f'psdi_data_conversion/scripts/{self.script}', *self._get_script_args()],
756
743
  env=env, capture_output=True, text=True)
757
744
 
758
745
  self.out = process.stdout
@@ -763,3 +750,20 @@ class ScriptFileConverter(FileConverter):
763
750
  self._abort_from_err()
764
751
  else:
765
752
  self.logger.debug("Conversion process completed successfully")
753
+
754
+ def _get_script_args(self):
755
+ """Get the list of arguments which will be passed to the script"""
756
+
757
+ from_flags = self.data.get("from_flags", "")
758
+ to_flags = self.data.get("from_flags", "")
759
+ from_options = self.data.get("from_options", "")
760
+ to_options = self.data.get("from_options", "")
761
+
762
+ # Check that all user-provided input passes security checks
763
+ for user_args in [from_flags, to_flags, from_options, to_options]:
764
+ if not string_is_safe(user_args):
765
+ raise FileConverterInputException(f"Provided argument '{user_args}' does not pass security check - it "
766
+ f"must match the regex {SAFE_STRING_RE.pattern}.", help=True)
767
+
768
+ return ['--' + self.to_format_info.name, self.in_filename, self.out_filename, from_flags, to_flags,
769
+ from_options, to_options]
@@ -29,6 +29,19 @@ class C2xFileConverter(ScriptFileConverter):
29
29
  "may be downloaded from https://www.c2x.org.uk/downloads/")
30
30
  supports_ambiguous_extensions = True
31
31
 
32
+ def _get_script_args(self):
33
+ """Override the standard script arguments so we can set the different format names expected by c2x
34
+ """
35
+ l_script_args = super()._get_script_args()
36
+
37
+ # Update the output format to c2x style
38
+ l_script_args[0] = "--" + self.to_format_info.c2x_format
39
+
40
+ # TODO - check if the input file has an extension which will be accepted by c2x for its format, and handle if
41
+ # not
42
+
43
+ return l_script_args
44
+
32
45
 
33
46
  # Assign this converter to the `converter` variable - this lets the psdi_data_conversion.converter module detect and
34
47
  # register it, making it available for use by the command-line script, python library, and web app
@@ -6,8 +6,9 @@ Open Babel FileConverter
6
6
  """
7
7
 
8
8
  from copy import deepcopy
9
- from openbabel import openbabel
9
+
10
10
  import py
11
+ from openbabel import openbabel
11
12
 
12
13
  from psdi_data_conversion.converters.base import FileConverter, FileConverterInputException
13
14
  from psdi_data_conversion.security import SAFE_STRING_RE, string_is_safe
@@ -7,12 +7,12 @@ Python module provide utilities for accessing the converter database
7
7
 
8
8
  from __future__ import annotations
9
9
 
10
+ import json
11
+ import os
10
12
  from dataclasses import dataclass, field
11
13
  from itertools import product
12
- import json
13
14
  from logging import getLogger
14
- import os
15
- from typing import Any, Literal
15
+ from typing import Any, Literal, overload
16
16
 
17
17
  from psdi_data_conversion import constants as const
18
18
  from psdi_data_conversion.converter import D_REGISTERED_CONVERTERS, D_SUPPORTED_CONVERTERS
@@ -32,6 +32,7 @@ DB_URL_KEY = "url"
32
32
 
33
33
  # Keys for format general info in the database
34
34
  DB_FORMAT_EXT_KEY = "extension"
35
+ DB_FORMAT_C2X_KEY = "format"
35
36
  DB_FORMAT_NOTE_KEY = "note"
36
37
  DB_FORMAT_COMP_KEY = "composition"
37
38
  DB_FORMAT_CONN_KEY = "connections"
@@ -428,6 +429,9 @@ class FormatInfo:
428
429
  self.id: int = d_single_format_info.get(DB_ID_KEY, -1)
429
430
  """The ID of this format"""
430
431
 
432
+ self.c2x_format: str = d_single_format_info.get(DB_FORMAT_C2X_KEY)
433
+ """The name of this format as the c2x converter expects it"""
434
+
431
435
  self.note: str = d_single_format_info.get(DB_FORMAT_NOTE_KEY, "")
432
436
  """The description of this format"""
433
437
 
@@ -708,8 +712,8 @@ class ConversionsTable:
708
712
  conversion, the second is the info of the input format for this conversion, and the third is the info of the
709
713
  output format
710
714
  """
711
- l_in_format_infos: list[FormatInfo] = self.parent.get_format_info(in_format, which="all")
712
- l_out_format_infos: list[FormatInfo] = self.parent.get_format_info(out_format, which="all")
715
+ l_in_format_infos = self.parent.get_format_info(in_format, which="all")
716
+ l_out_format_infos = self.parent.get_format_info(out_format, which="all")
713
717
 
714
718
  # Start a list of all possible conversions
715
719
  l_possible_conversions = []
@@ -934,6 +938,16 @@ class DataConversionDatabase:
934
938
  f" of type '{type(converter_name_or_id)}'. Type must be `str` or "
935
939
  "`int`")
936
940
 
941
+ @overload
942
+ def get_format_info(self,
943
+ format_name_or_id: str | int | FormatInfo,
944
+ which: int | None = None) -> FormatInfo: ...
945
+
946
+ @overload
947
+ def get_format_info(self,
948
+ format_name_or_id: str | int | FormatInfo,
949
+ which: Literal["all"]) -> list[FormatInfo]: ...
950
+
937
951
  def get_format_info(self,
938
952
  format_name_or_id: str | int | FormatInfo,
939
953
  which: int | Literal["all"] | None = None) -> FormatInfo | list[FormatInfo]:
@@ -1084,6 +1098,16 @@ def get_converter_info(name: str) -> ConverterInfo:
1084
1098
  return get_database().d_converter_info[name]
1085
1099
 
1086
1100
 
1101
+ @overload
1102
+ def get_format_info(format_name_or_id: str | int | FormatInfo,
1103
+ which: int | None = None) -> FormatInfo: ...
1104
+
1105
+
1106
+ @overload
1107
+ def get_format_info(format_name_or_id: str | int | FormatInfo,
1108
+ which: Literal["all"]) -> list[FormatInfo]: ...
1109
+
1110
+
1087
1111
  def get_format_info(format_name_or_id: str | int | FormatInfo,
1088
1112
  which: int | Literal["all"] | None = None) -> FormatInfo | list[FormatInfo]:
1089
1113
  """Gets the information on a given file format stored in the database
@@ -7,9 +7,10 @@ Functions and utilities related to handling multiple user OSes and distributions
7
7
 
8
8
  import os
9
9
  import shutil
10
- import psdi_data_conversion
11
10
  import sys
12
11
 
12
+ import psdi_data_conversion
13
+
13
14
  # Labels for each platform (which we use for the folder in this project), and the head of the name each platform will
14
15
  # have in `sys.platform`
15
16
 
@@ -149,8 +149,7 @@ def pack_zip_or_tar(archive_filename: str,
149
149
  archive_format = _format
150
150
  archive_root_filename = split_archive_ext(archive_filename)[0]
151
151
  break
152
- # Check that the format was found
153
- if archive_format is None:
152
+ else:
154
153
  raise AssertionError("Invalid execution path entered - filename wasn't found with a valid archive "
155
154
  "extension, but it did pass the `is_supported_archive` check")
156
155
  else:
@@ -7,12 +7,12 @@ Created 2025-01-14 by Bryan Gillis.
7
7
  Entry-point file for the command-line interface for data conversion.
8
8
  """
9
9
 
10
- from itertools import product
11
10
  import logging
12
- from argparse import ArgumentParser
13
11
  import os
14
12
  import sys
15
13
  import textwrap
14
+ from argparse import ArgumentParser
15
+ from itertools import product
16
16
 
17
17
  from psdi_data_conversion import constants as const
18
18
  from psdi_data_conversion.constants import CL_SCRIPT_NAME, CONVERTER_DEFAULT, TERM_WIDTH
@@ -537,7 +537,7 @@ def detail_format(format_name: str):
537
537
  """Prints details on a format
538
538
  """
539
539
 
540
- l_format_info: list[FormatInfo] = get_format_info(format_name, which="all")
540
+ l_format_info = get_format_info(format_name, which="all")
541
541
 
542
542
  if len(l_format_info) == 0:
543
543
  print_wrap(f"ERROR: Format '{format_name}' not recognised", err=True, newline=True)
@@ -17,16 +17,20 @@
17
17
  </ul>
18
18
  <ul class="footer__col footer__items clean-list">
19
19
  <li>
20
- <img class="lm-only" src="static/img/ukri-logo-lighttext.png"
21
- alt="UKRI logo">
22
- <img class="dm-only" src="static/img/ukri-logo-darktext.png"
23
- alt="UKRI logo">
20
+ <a href="https://www.ukri.org/">
21
+ <img class="lm-only" src="static/img/ukri-logo-lighttext.png"
22
+ alt="UKRI logo">
23
+ <img class="dm-only" src="static/img/ukri-logo-darktext.png"
24
+ alt="UKRI logo">
25
+ </a>
24
26
  </li>
25
27
  <li>
26
- <img class="lm-only" src="static/img/ukri-epsr-logo-lighttext.png"
27
- alt="UKRI EPSR logo">
28
- <img class="dm-only" src="static/img/ukri-epsr-logo-darktext.png"
29
- alt="UKRI EPSR logo">
28
+ <a href="https://www.ukri.org/councils/epsrc/">
29
+ <img class="lm-only" src="static/img/ukri-epsr-logo-lighttext.png"
30
+ alt="UKRI EPSR logo">
31
+ <img class="dm-only" src="static/img/ukri-epsr-logo-darktext.png"
32
+ alt="UKRI EPSR logo">
33
+ </a>
30
34
  </li>
31
35
  </ul>
32
36
  <div class="footer__hline small-screen-only">
@@ -17,16 +17,20 @@
17
17
  </ul>
18
18
  <ul class="footer__col footer__items clean-list">
19
19
  <li>
20
- <img class="lm-only" src="../img/ukri-logo-lighttext.png"
21
- alt="UKRI logo">
22
- <img class="dm-only" src="../img/ukri-logo-darktext.png"
23
- alt="UKRI logo">
20
+ <a href="https://www.ukri.org/">
21
+ <img class="lm-only" src="../img/ukri-logo-lighttext.png"
22
+ alt="UKRI logo">
23
+ <img class="dm-only" src="../img/ukri-logo-darktext.png"
24
+ alt="UKRI logo">
25
+ </a>
24
26
  </li>
25
27
  <li>
26
- <img class="lm-only" src="../img/ukri-epsr-logo-lighttext.png"
27
- alt="UKRI EPSR logo">
28
- <img class="dm-only" src="../img/ukri-epsr-logo-darktext.png"
29
- alt="UKRI EPSR logo">
28
+ <a href="https://www.ukri.org/councils/epsrc/">
29
+ <img class="lm-only" src="../img/ukri-epsr-logo-lighttext.png"
30
+ alt="UKRI EPSR logo">
31
+ <img class="dm-only" src="../img/ukri-epsr-logo-darktext.png"
32
+ alt="UKRI EPSR logo">
33
+ </a>
30
34
  </li>
31
35
  </ul>
32
36
  <div class="footer__hline small-screen-only">