psdi-data-conversion 0.0.37__py3-none-any.whl → 0.0.39__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.
- psdi_data_conversion/app.py +64 -14
- psdi_data_conversion/constants.py +6 -5
- psdi_data_conversion/converter.py +20 -13
- psdi_data_conversion/converters/base.py +75 -68
- psdi_data_conversion/converters/c2x.py +14 -0
- psdi_data_conversion/converters/openbabel.py +12 -11
- psdi_data_conversion/database.py +361 -115
- psdi_data_conversion/dist.py +2 -1
- psdi_data_conversion/file_io.py +1 -2
- psdi_data_conversion/log_utility.py +1 -1
- psdi_data_conversion/main.py +152 -70
- psdi_data_conversion/static/content/index-versions/psdi-common-footer.html +12 -8
- psdi_data_conversion/static/content/psdi-common-footer.html +12 -8
- psdi_data_conversion/static/data/data.json +617 -3
- psdi_data_conversion/static/javascript/convert.js +54 -6
- psdi_data_conversion/static/javascript/convert_common.js +16 -2
- psdi_data_conversion/static/javascript/data.js +36 -4
- psdi_data_conversion/static/javascript/format.js +22 -9
- psdi_data_conversion/static/styles/format.css +7 -0
- psdi_data_conversion/templates/index.htm +57 -48
- psdi_data_conversion/testing/constants.py +3 -0
- psdi_data_conversion/testing/conversion_callbacks.py +4 -3
- psdi_data_conversion/testing/conversion_test_specs.py +44 -20
- psdi_data_conversion/testing/gui.py +362 -294
- psdi_data_conversion/testing/utils.py +38 -19
- {psdi_data_conversion-0.0.37.dist-info → psdi_data_conversion-0.0.39.dist-info}/METADATA +88 -4
- {psdi_data_conversion-0.0.37.dist-info → psdi_data_conversion-0.0.39.dist-info}/RECORD +30 -30
- {psdi_data_conversion-0.0.37.dist-info → psdi_data_conversion-0.0.39.dist-info}/WHEEL +0 -0
- {psdi_data_conversion-0.0.37.dist-info → psdi_data_conversion-0.0.39.dist-info}/entry_points.txt +0 -0
- {psdi_data_conversion-0.0.37.dist-info → psdi_data_conversion-0.0.39.dist-info}/licenses/LICENSE +0 -0
@@ -7,7 +7,9 @@
|
|
7
7
|
|
8
8
|
|
9
9
|
import { getInputFlags, getOutputFlags, getInputArgFlags, getOutputArgFlags } from "./data.js";
|
10
|
-
import {
|
10
|
+
import {
|
11
|
+
SAFE_CHAR_REGEX, commonConvertReady, convertFile, getExtCheck, splitArchiveExt, isArchiveExt
|
12
|
+
} from "./convert_common.js"
|
11
13
|
|
12
14
|
var token = "",
|
13
15
|
in_ext = "",
|
@@ -51,8 +53,24 @@ function enterArgument(event) {
|
|
51
53
|
}
|
52
54
|
}
|
53
55
|
|
56
|
+
|
57
|
+
/**
|
58
|
+
* Validate the input for a format option - if invalid, display the error message, if valid, hide it
|
59
|
+
*
|
60
|
+
* @param {*} event
|
61
|
+
*/
|
62
|
+
function validateInput(event) {
|
63
|
+
var err_id = this.id.replace('text', 'err')
|
64
|
+
if (this.validity.patternMismatch) {
|
65
|
+
$('#' + err_id).css({ display: "block" })
|
66
|
+
} else {
|
67
|
+
$('#' + err_id).css({ display: "none" })
|
68
|
+
}
|
69
|
+
}
|
70
|
+
|
54
71
|
// Uploads a user-supplied file
|
55
72
|
function submitFile() {
|
73
|
+
|
56
74
|
const file = $("#fileToUpload")[0].files[0],
|
57
75
|
[fname, ext] = splitArchiveExt(file.name);
|
58
76
|
|
@@ -78,9 +96,16 @@ function submitFile() {
|
|
78
96
|
const checked_in = $('input[name=in_arg_check]:checked'),
|
79
97
|
checked_out = $('input[name=out_arg_check]:checked');
|
80
98
|
|
99
|
+
let security_passed = true;
|
100
|
+
|
81
101
|
checked_in.each(function () {
|
82
102
|
read_arg_flags += $("#" + this.id).val()[0];
|
83
|
-
const
|
103
|
+
const e = $("#in_arg_text" + this.id.substring(this.id.length - 1, this.id.length));
|
104
|
+
const arg = e.val();
|
105
|
+
|
106
|
+
if (e[0].validity.patternMismatch) {
|
107
|
+
security_passed = false;
|
108
|
+
}
|
84
109
|
|
85
110
|
if (/\S/.test(arg)) {
|
86
111
|
read_args += arg.trim() + '£';
|
@@ -92,7 +117,12 @@ function submitFile() {
|
|
92
117
|
|
93
118
|
checked_out.each(function () {
|
94
119
|
write_arg_flags += $("#" + this.id).val()[0];
|
95
|
-
const
|
120
|
+
const e = $("#out_arg_text" + this.id.substring(this.id.length - 1, this.id.length));
|
121
|
+
const arg = e.val();
|
122
|
+
|
123
|
+
if (e[0].validity.patternMismatch) {
|
124
|
+
security_passed = false;
|
125
|
+
}
|
96
126
|
|
97
127
|
if (/\S/.test(arg)) {
|
98
128
|
write_args += arg.trim() + '£';
|
@@ -102,9 +132,21 @@ function submitFile() {
|
|
102
132
|
}
|
103
133
|
})
|
104
134
|
|
135
|
+
let alert_msg = '';
|
136
|
+
|
137
|
+
if (!security_passed) {
|
138
|
+
alert_msg += 'ERROR: One or more ticked options contains invalid characters. They must match the regex /' +
|
139
|
+
SAFE_CHAR_REGEX + '/ .\n';
|
140
|
+
}
|
141
|
+
|
105
142
|
if (!all_args_entered) {
|
106
|
-
|
107
|
-
|
143
|
+
alert_msg += 'ERROR: All ticked options need additional information to be entered into the associated ' +
|
144
|
+
'text box.\n';
|
145
|
+
}
|
146
|
+
|
147
|
+
if (alert_msg) {
|
148
|
+
alert(alert_msg);
|
149
|
+
return
|
108
150
|
}
|
109
151
|
|
110
152
|
const coordinates = $('input[name="coordinates"]:checked').val(),
|
@@ -216,11 +258,17 @@ function addCheckboxes(argFlags, type) {
|
|
216
258
|
<tr>
|
217
259
|
<td><input type='checkbox' id="${type}_check${flagCount}" name=${type}_check value="${flag}"></input></td>
|
218
260
|
<td><label for="${type}_check${flagCount}">${flag} [${brief}]: ${description}<label></td>
|
219
|
-
<td><input type='text' id
|
261
|
+
<td><input type='text' id="${type}_text${flagCount}" placeholder='-- type info. here --'
|
262
|
+
pattern='` + SAFE_CHAR_REGEX + `'></input>
|
263
|
+
<p class="init-hidden" id="${type}_err${flagCount}"><strong>ERROR:</strong> Input contains
|
264
|
+
invalid characters; it must match the regex
|
265
|
+
<code class="secondary">/` + SAFE_CHAR_REGEX + `/</code></p>
|
266
|
+
</td>
|
220
267
|
<td><span id= ${type}_label${flagCount}>${furtherInfo}</span></td>
|
221
268
|
</tr>`);
|
222
269
|
|
223
270
|
$(`#${type}_text${flagCount}`).hide();
|
271
|
+
$(`#${type}_text${flagCount}`).on('input', validateInput);
|
224
272
|
$(`#${type}_label${flagCount}`).hide();
|
225
273
|
$(`#${type}_check${flagCount}`).change(enterArgument);
|
226
274
|
|
@@ -18,6 +18,20 @@ const TARGZ_EXT = "tar.gz"
|
|
18
18
|
const TARBZ_EXT = "tar.bz"
|
19
19
|
const TARXZ_EXT = "tar.xz"
|
20
20
|
|
21
|
+
// Short list of safe allowed characters:
|
22
|
+
// \w: All letters and digits
|
23
|
+
// \s: All whitespace characters
|
24
|
+
// .: Period
|
25
|
+
// \-: Hyphen
|
26
|
+
// :: Colon
|
27
|
+
// +: Plus symbol
|
28
|
+
// *: Asterisk
|
29
|
+
// =: Equals sign
|
30
|
+
// $: Dollar sign
|
31
|
+
// /: Forward-slash
|
32
|
+
// \\: Backslash
|
33
|
+
export const SAFE_CHAR_REGEX = "[\\w\\s.\\-:+*=$\\/\\\\]*"
|
34
|
+
|
21
35
|
// Whether or not file extensions will be checked
|
22
36
|
let extCheck = true;
|
23
37
|
|
@@ -271,10 +285,10 @@ function checkFile(event) {
|
|
271
285
|
}
|
272
286
|
|
273
287
|
/**
|
274
|
-
* Allow the file upload to only accept the expected type of file
|
288
|
+
* Allow the file upload to only accept the expected type of file, plus archives
|
275
289
|
*/
|
276
290
|
function limitFileType() {
|
277
|
-
$("#fileToUpload")[0].accept = "." + in_ext;
|
291
|
+
$("#fileToUpload")[0].accept = "." + in_ext + ", .zip, .tar, .tar.gz, .tar.xz, .tar.bz";
|
278
292
|
}
|
279
293
|
|
280
294
|
/**
|
@@ -1,7 +1,21 @@
|
|
1
1
|
// data.js
|
2
2
|
|
3
3
|
const response = await fetch("/static/data/data.json");
|
4
|
-
|
4
|
+
|
5
|
+
let data = null;
|
6
|
+
try {
|
7
|
+
data = JSON.parse(await response.text());
|
8
|
+
} catch (err) {
|
9
|
+
console.log("ERROR: Database could not be loaded, error: " + err)
|
10
|
+
}
|
11
|
+
|
12
|
+
/**
|
13
|
+
* Indicates whether or not the database was successfully loaded
|
14
|
+
* @returns {boolean}
|
15
|
+
*/
|
16
|
+
export function databaseLoaded() {
|
17
|
+
return data !== null;
|
18
|
+
}
|
5
19
|
|
6
20
|
const collator = new Intl.Collator();
|
7
21
|
|
@@ -49,6 +63,24 @@ export async function getOutputFormats() {
|
|
49
63
|
return outFormats.sort((a, b) => compare([a.extension, b.extension], [a.note, b.note]))
|
50
64
|
}
|
51
65
|
|
66
|
+
/**
|
67
|
+
* Gets the ID for a format, given its extension and note
|
68
|
+
*
|
69
|
+
* @param {string} extension - The extension of the format, e.g. 'pdb'
|
70
|
+
* @param {string} note - The note of the format, e.g. 'Protein Databank'
|
71
|
+
* @returns {(int|null)} - The ID of the format if found, or else null
|
72
|
+
*/
|
73
|
+
export async function getFormatId(extension, note) {
|
74
|
+
|
75
|
+
var format = (data.formats.filter(format => (format.extension === extension) && (format.note === note)));
|
76
|
+
|
77
|
+
if (format === undefined) {
|
78
|
+
return null;
|
79
|
+
}
|
80
|
+
|
81
|
+
return format[0].id;
|
82
|
+
}
|
83
|
+
|
52
84
|
export async function getOutputFormatsForInputFormat(inExtension, inNote) {
|
53
85
|
|
54
86
|
const inputFormat = (data.formats.filter(format => (format.extension === inExtension) && (format.note === inNote)))[0];
|
@@ -84,7 +116,7 @@ export async function getConverters(inExtension, inNote, outExtension, outNote)
|
|
84
116
|
const inputFormat = (data.formats.filter(format => (format.extension === inExtension) && (format.note === inNote)))[0];
|
85
117
|
const outputFormat = (data.formats.filter(format => (format.extension === outExtension) && (format.note === outNote)))[0];
|
86
118
|
|
87
|
-
if ((inputFormat === undefined) || (outputFormat === undefined))
|
119
|
+
if ((inputFormat === undefined) || (outputFormat === undefined)) {
|
88
120
|
return [];
|
89
121
|
}
|
90
122
|
|
@@ -96,7 +128,7 @@ export async function getConverters(inExtension, inNote, outExtension, outNote)
|
|
96
128
|
name: convertersById.get(conversion.converters_id).name
|
97
129
|
}));
|
98
130
|
|
99
|
-
return convertersWithDegreeOfSuccess.sort((a, b) => compare(a.name, b.name
|
131
|
+
return convertersWithDegreeOfSuccess.sort((a, b) => compare(a.name, b.name));
|
100
132
|
}
|
101
133
|
|
102
134
|
export async function getConverterByName(name) {
|
@@ -170,7 +202,7 @@ export async function getOutputArgFlags(extension, note) {
|
|
170
202
|
export async function getLevelChemInfo(inExtension, inNote, outExtension, outNote) {
|
171
203
|
|
172
204
|
const inputFormat = (data.formats.filter(format => (format.extension === inExtension) && (format.note === inNote)))[0],
|
173
|
-
|
205
|
+
outputFormat = (data.formats.filter(format => (format.extension === outExtension) && (format.note === outNote)))[0];
|
174
206
|
|
175
207
|
return [inputFormat, outputFormat];
|
176
208
|
}
|
@@ -7,7 +7,7 @@
|
|
7
7
|
|
8
8
|
import { disableDirtyForms, cleanDirtyForms, initDirtyForms, loadServiceMode, loadProductionMode } from "./common.js";
|
9
9
|
import {
|
10
|
-
getInputFormats, getOutputFormats, getOutputFormatsForInputFormat,
|
10
|
+
databaseLoaded, getInputFormats, getOutputFormats, getOutputFormatsForInputFormat,
|
11
11
|
getInputFormatsForOutputFormat, getConverters, getConverterByName, getLevelChemInfo
|
12
12
|
} from "./data.js";
|
13
13
|
|
@@ -18,15 +18,20 @@ var fromList = new Array(),
|
|
18
18
|
|
19
19
|
$(document).ready(function () {
|
20
20
|
|
21
|
-
//
|
22
|
-
|
23
|
-
|
24
|
-
|
21
|
+
// Populate the available formats if the database successfully loaded, otherwise display an error message
|
22
|
+
if (databaseLoaded()) {
|
23
|
+
// Populates the "Convert from" selection list
|
24
|
+
getInputFormats().then((formats) => {
|
25
|
+
populateList(formats, "from");
|
26
|
+
});
|
25
27
|
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
28
|
+
// Populates the "Convert to" selection list
|
29
|
+
getOutputFormats().then((formats) => {
|
30
|
+
populateList(formats, "to");
|
31
|
+
});
|
32
|
+
} else {
|
33
|
+
displayDatabaseLoadError();;
|
34
|
+
}
|
30
35
|
|
31
36
|
sessionStorage.setItem("token", token);
|
32
37
|
sessionStorage.setItem("max_file_size", max_file_size);
|
@@ -52,6 +57,14 @@ $(document).ready(function () {
|
|
52
57
|
initDirtyForms();
|
53
58
|
});
|
54
59
|
|
60
|
+
/**
|
61
|
+
* Hides the format and converter selection and displays an error message that the database could not be loaded.
|
62
|
+
*/
|
63
|
+
function displayDatabaseLoadError() {
|
64
|
+
$("#format-selection").css({ display: "none" });
|
65
|
+
$("#database-error").css({ display: "block" });
|
66
|
+
}
|
67
|
+
|
55
68
|
/**
|
56
69
|
* Gets the input and output extensions and their notes from what's currently selected in the search boxes.
|
57
70
|
* @returns {Array<str>} Input extension, Input note, Output extension, Output note
|
@@ -44,6 +44,13 @@ form {
|
|
44
44
|
}
|
45
45
|
}
|
46
46
|
|
47
|
+
/* Invalid input fields switch to alternate background */
|
48
|
+
|
49
|
+
input:invalid {
|
50
|
+
background-color: var(--ifm-color-primary);
|
51
|
+
color : var(--ifm-hero-text-color);
|
52
|
+
}
|
53
|
+
|
47
54
|
/* Converter details, user input and file conversion initially not displayed. */
|
48
55
|
.init-hidden {
|
49
56
|
display: none
|
@@ -60,55 +60,64 @@
|
|
60
60
|
<p>Your one-stop shop for file format conversion, PSDI's Data Conversion Service enables users to seamlessly
|
61
61
|
convert between different file formats and assess the quality of proposed conversions. This is the web version
|
62
62
|
of our service. To find out more about Data Conversion and our other tools, click
|
63
|
-
<a href="https://resources.psdi.ac.uk/resource-themes/7bcc430a-fdc9-413e-bf32-bf163236430b"
|
64
|
-
|
65
|
-
<p>Select 'from' and 'to' file formats in the 'Convert from/to' boxes, in either order. Typing where indicated
|
66
|
-
filters the options (case insensitive); for example, typing 'can' or 'NON' reduces the number of options to one:
|
67
|
-
'can: Canonical SMILES.' If you change your mind about a conversion, it is advisable to click on the 'Reset'
|
68
|
-
button. When both formats have been selected, converters able to carry out this conversion appear in the
|
69
|
-
'Conversion options' box along with an indication of conversion quality (many conversions have not yet been
|
70
|
-
tested) and whether or not the converter is supported on this site.</p>
|
71
|
-
<p>
|
72
|
-
<label for="searchFrom" id="fromLabel">Convert from:</label><br>
|
73
|
-
<input type="text" placeholder="-- type here to filter options --" size="12" id="searchFrom"
|
74
|
-
class="large-width"><br>
|
75
|
-
<select size="4" id="fromList" class="large-width"></select>
|
63
|
+
<a href="https://resources.psdi.ac.uk/resource-themes/7bcc430a-fdc9-413e-bf32-bf163236430b" id="more"
|
64
|
+
target="_blank">here.</a>
|
76
65
|
</p>
|
77
|
-
<div
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
<
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
<
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
66
|
+
<div id="format-selection">
|
67
|
+
<p>Select 'from' and 'to' file formats in the 'Convert from/to' boxes, in either order. Typing where indicated
|
68
|
+
filters the options (case insensitive); for example, typing 'can' or 'NON' reduces the number of options to
|
69
|
+
one:
|
70
|
+
'can: Canonical SMILES.' If you change your mind about a conversion, it is advisable to click on the 'Reset'
|
71
|
+
button. When both formats have been selected, converters able to carry out this conversion appear in the
|
72
|
+
'Conversion options' box along with an indication of conversion quality (many conversions have not yet been
|
73
|
+
tested) and whether or not the converter is supported on this site.</p>
|
74
|
+
<p>
|
75
|
+
<label for="searchFrom" id="fromLabel">Convert from:</label><br>
|
76
|
+
<input type="text" placeholder="-- type here to filter options --" size="12" id="searchFrom"
|
77
|
+
class="large-width"><br>
|
78
|
+
<select size="4" id="fromList" class="large-width"></select>
|
79
|
+
</p>
|
80
|
+
<div class="smallGap"></div>
|
81
|
+
<p>
|
82
|
+
<label for="searchTo" id="toLabel">Convert to:</label><br>
|
83
|
+
<input type="text" placeholder="-- type here to filter options --" size="12" id="searchTo"
|
84
|
+
class="large-width"><br>
|
85
|
+
<select size="4" id="toList" class="large-width"></select>
|
86
|
+
</p>
|
87
|
+
<input type="button" class="button" value=" Reset " name="resetButton" id="resetButton">
|
88
|
+
<br><br>
|
89
|
+
<p>Selecting a converter displays information
|
90
|
+
about it, along with a link to a relevant website. Selecting a supported converter affords the opportunity to
|
91
|
+
carry out a conversion on this site. Clicking on the 'Yes' button takes us to the 'Conversion' page. If a
|
92
|
+
file format has not been found, or if there are no converters capable of carrying out a required conversion
|
93
|
+
please click on 'Report Missing Format/Conversion' in the navigation bar.</p>
|
94
|
+
<p>
|
95
|
+
<label for="success">Select from available conversion
|
96
|
+
options:</label><br>
|
97
|
+
<select size="4" id="success" class="large-width"></select>
|
98
|
+
</p>
|
99
|
+
<span class="normalText">Show how the conversion quality was determined for the selected converter.</span>
|
100
|
+
<input type="button" class="button" value=" Show " name="showButton" id="showButton">
|
101
|
+
<br>
|
102
|
+
<h6>Converter details:</h6>
|
103
|
+
<p id="converter" , class="init-hidden">
|
104
|
+
<span id="name"></span>
|
105
|
+
<br><span id="description"></span>
|
106
|
+
<br><span id="url"></span>
|
107
|
+
<br><span id="info"></span>
|
108
|
+
<a id="visit" target="_blank">this website.</a>
|
109
|
+
<div id="formatWarning" class="init-hidden"></div>
|
110
|
+
<div id="offer" class="init-hidden">
|
111
|
+
<span id="question"></span>
|
112
|
+
<input type="button" class="button" value=" Yes " name="yesButton" id="yesButton">
|
113
|
+
</div>
|
114
|
+
</p>
|
115
|
+
</div>
|
116
|
+
<div id="database-error" class="init-hidden">
|
117
|
+
<p><strong>ERROR:</strong> Connection to the conversion database failed. Please try refreshing this page. If
|
118
|
+
this issue persists, please report it to us using the "Contact" link in the header. You can also download
|
119
|
+
a version of this service for local use using the "Download" link in the header if you'd prefer.</p>
|
110
120
|
</div>
|
111
|
-
</p>
|
112
121
|
<div class="medGap"></div>
|
113
122
|
</div>
|
114
123
|
</form>
|
@@ -123,4 +132,4 @@
|
|
123
132
|
|
124
133
|
</body>
|
125
134
|
|
126
|
-
</html>
|
135
|
+
</html>
|
@@ -13,3 +13,6 @@ TEST_DATA_LOC_IN_PROJECT = "./test_data"
|
|
13
13
|
|
14
14
|
INPUT_TEST_DATA_LOC_IN_PROJECT = TEST_DATA_LOC_IN_PROJECT
|
15
15
|
OUTPUT_TEST_DATA_LOC_IN_PROJECT = os.path.join(TEST_DATA_LOC_IN_PROJECT, "output")
|
16
|
+
|
17
|
+
DEFAULT_ORIGIN = "http://127.0.0.1:5000"
|
18
|
+
"""The default location of the server for running GUI unit tests"""
|
@@ -6,10 +6,10 @@ conversion test, run with the functions and classes defined in the `utils.py` mo
|
|
6
6
|
"""
|
7
7
|
|
8
8
|
import abc
|
9
|
-
from collections.abc import Callable, Iterable
|
10
|
-
from dataclasses import dataclass, field
|
11
9
|
import os
|
12
10
|
import re
|
11
|
+
from collections.abc import Callable, Iterable
|
12
|
+
from dataclasses import dataclass, field
|
13
13
|
from tempfile import TemporaryDirectory
|
14
14
|
|
15
15
|
from psdi_data_conversion.constants import DATETIME_RE_RAW
|
@@ -352,7 +352,8 @@ class CheckException:
|
|
352
352
|
|
353
353
|
# Check the exception type
|
354
354
|
if self.ex_type and not issubclass(exc_info.type, self.ex_type):
|
355
|
-
l_errors.append(f"ERROR: Raised exception is of type '{exc_info.type}', but expected '{self.ex_type}'"
|
355
|
+
l_errors.append(f"ERROR: Raised exception is of type '{exc_info.type}', but expected '{self.ex_type}'. "
|
356
|
+
f"Raised exception's message was: {str(exc_info)}")
|
356
357
|
|
357
358
|
exc = exc_info.value
|
358
359
|
|
@@ -8,17 +8,18 @@ application, and GUI.
|
|
8
8
|
|
9
9
|
from psdi_data_conversion import constants as const
|
10
10
|
from psdi_data_conversion.converters.atomsk import CONVERTER_ATO
|
11
|
-
from psdi_data_conversion.converters.base import (FileConverterAbortException,
|
12
|
-
|
11
|
+
from psdi_data_conversion.converters.base import (FileConverterAbortException, FileConverterInputException,
|
12
|
+
FileConverterSizeException)
|
13
13
|
from psdi_data_conversion.converters.c2x import CONVERTER_C2X
|
14
14
|
from psdi_data_conversion.converters.openbabel import CONVERTER_OB, COORD_GEN_KEY, COORD_GEN_QUAL_KEY
|
15
|
-
from psdi_data_conversion.
|
16
|
-
|
15
|
+
from psdi_data_conversion.database import FileConverterDatabaseException
|
16
|
+
from psdi_data_conversion.testing.conversion_callbacks import (CheckArchiveContents, CheckException, CheckFileStatus,
|
17
|
+
CheckLogContents, CheckLogContentsSuccess,
|
17
18
|
CheckStderrContents, CheckStdoutContents,
|
18
|
-
MatchOutputFile
|
19
|
+
MatchOutputFile)
|
20
|
+
from psdi_data_conversion.testing.conversion_callbacks import MultiCallback as MCB
|
19
21
|
from psdi_data_conversion.testing.utils import ConversionTestSpec as Spec
|
20
22
|
|
21
|
-
|
22
23
|
l_all_test_specs: list[Spec] = []
|
23
24
|
"""All test specs defined in this file"""
|
24
25
|
|
@@ -36,11 +37,16 @@ l_all_test_specs.append(Spec(name="Standard Multiple Tests",
|
|
36
37
|
"hemoglobin.pdb", "hemoglobin.pdb", "nacl.cif",
|
37
38
|
"hemoglobin.pdb", "hemoglobin.pdb", "nacl.cif",
|
38
39
|
"ethanol.xyz"],
|
39
|
-
to_format=["pdb",
|
40
|
+
to_format=["pdb-0",
|
40
41
|
"cif", "mol2", "xyz",
|
41
42
|
"cif", "xyz", "xyz",
|
42
|
-
"cif", "xyz", "xyz",
|
43
|
+
"cif", "xyz-0", "xyz-0",
|
43
44
|
"cml"],
|
45
|
+
from_format=[None,
|
46
|
+
None, None, None,
|
47
|
+
None, None, None,
|
48
|
+
"pdb-0", "pdb-0", None,
|
49
|
+
None],
|
44
50
|
converter_name=[CONVERTER_OB,
|
45
51
|
CONVERTER_OB, CONVERTER_OB, CONVERTER_OB,
|
46
52
|
CONVERTER_ATO, CONVERTER_ATO, CONVERTER_ATO,
|
@@ -52,6 +58,17 @@ l_all_test_specs.append(Spec(name="Standard Multiple Tests",
|
|
52
58
|
"""A basic set of test conversions which we expect to succeed without issue, running conversions with each of the
|
53
59
|
Open Babel, Atomsk, and c2x converters"""
|
54
60
|
|
61
|
+
l_all_test_specs.append(Spec(name="c2x Formats Tests",
|
62
|
+
to_format=["res", "abi", "POSCAR", "cml"],
|
63
|
+
converter_name=CONVERTER_C2X,
|
64
|
+
callback=MCB(CheckFileStatus(),
|
65
|
+
CheckLogContentsSuccess()),
|
66
|
+
compatible_with_gui=False,
|
67
|
+
))
|
68
|
+
"""Test converting with c2x to a few different formats which require special input. This test isn't run in the GUI
|
69
|
+
solely to save on resources, since there are unlikely to be an GUI-specific issues raised by this test that aren't
|
70
|
+
caught in others."""
|
71
|
+
|
55
72
|
archive_callback = MCB(CheckFileStatus(),
|
56
73
|
CheckArchiveContents(l_filename_bases=["caffeine-no-flags",
|
57
74
|
"caffeine-ia",
|
@@ -65,7 +82,7 @@ l_all_test_specs.append(Spec(name="Archive",
|
|
65
82
|
filename=["caffeine-smi.zip",
|
66
83
|
"caffeine-smi.tar",
|
67
84
|
"caffeine-smi.tar.gz"],
|
68
|
-
|
85
|
+
from_format="smi",
|
69
86
|
to_format="inchi",
|
70
87
|
callback=archive_callback,
|
71
88
|
))
|
@@ -74,8 +91,8 @@ l_all_test_specs.append(Spec(name="Archive",
|
|
74
91
|
l_all_test_specs.append(Spec(name="Archive (wrong format) - Library and CLA",
|
75
92
|
filename="caffeine-smi.zip",
|
76
93
|
to_format="inchi",
|
77
|
-
|
78
|
-
|
94
|
+
from_format=["pdb-0", "pdb-0"],
|
95
|
+
conversion_kwargs=[{}, {"strict": True}],
|
79
96
|
expect_success=[True, False],
|
80
97
|
callback=[CheckStderrContents(const.ERR_WRONG_EXTENSIONS),
|
81
98
|
CheckException(ex_type=FileConverterInputException,
|
@@ -88,8 +105,8 @@ l_all_test_specs.append(Spec(name="Archive (wrong format) - Library and CLA",
|
|
88
105
|
l_all_test_specs.append(Spec(name="Archive (wrong format) - GUI",
|
89
106
|
filename="caffeine-smi.zip",
|
90
107
|
to_format="inchi",
|
91
|
-
|
92
|
-
|
108
|
+
from_format=["pdb-0", "pdb-0"],
|
109
|
+
conversion_kwargs=[{}, {"strict": True}],
|
93
110
|
expect_success=[False, False],
|
94
111
|
callback=CheckException(ex_type=FileConverterInputException,
|
95
112
|
ex_message=const.ERR_WRONG_EXTENSIONS),
|
@@ -150,7 +167,7 @@ Not compatible with GUI tests, since the GUI doesn't support quiet mode
|
|
150
167
|
|
151
168
|
l_all_test_specs.append(Spec(name="Open Babel Warning",
|
152
169
|
filename="1NE6.mmcif",
|
153
|
-
to_format="pdb",
|
170
|
+
to_format="pdb-0",
|
154
171
|
callback=CheckLogContentsSuccess(["Open Babel Warning",
|
155
172
|
"Failed to kekulize aromatic bonds",])
|
156
173
|
))
|
@@ -204,7 +221,8 @@ Not compatible with the GUI, since the GUI can't forcibly delete files uploaded
|
|
204
221
|
|
205
222
|
l_all_test_specs.append(Spec(name="Failed conversion - bad input file",
|
206
223
|
filename=["quartz_err.xyz", "cyclopropane_err.mol"],
|
207
|
-
to_format=["inchi", "xyz"],
|
224
|
+
to_format=["inchi", "xyz-0"],
|
225
|
+
from_format=[None, "mol-0"],
|
208
226
|
expect_success=False,
|
209
227
|
converter_name=[CONVERTER_OB, CONVERTER_C2X],
|
210
228
|
callback=[MCB(CheckFileStatus(expect_output_exists=False,
|
@@ -246,12 +264,13 @@ l_all_test_specs.append(Spec(name="Errors in logs - GUI",
|
|
246
264
|
|
247
265
|
l_all_test_specs.append(Spec(name="Failed conversion - invalid conversion",
|
248
266
|
filename=["Fapatite.ins", "nacl.mol"],
|
267
|
+
from_format=["ins", "mol-0"],
|
249
268
|
to_format=["cml", "xyz"],
|
250
269
|
expect_success=False,
|
251
|
-
converter_name=[
|
270
|
+
converter_name=[CONVERTER_C2X, CONVERTER_ATO],
|
252
271
|
callback=MCB(CheckFileStatus(expect_output_exists=False,
|
253
272
|
expect_log_exists=None),
|
254
|
-
CheckException(ex_type=
|
273
|
+
CheckException(ex_type=FileConverterDatabaseException,
|
255
274
|
ex_message="is not supported")),
|
256
275
|
compatible_with_gui=False,
|
257
276
|
))
|
@@ -263,7 +282,8 @@ Not compatible with the GUI, since the GUI only offers valid conversions.
|
|
263
282
|
l_all_test_specs.append(Spec(name="Blocked conversion - wrong input type",
|
264
283
|
filename="1NE6.mmcif",
|
265
284
|
to_format="cif",
|
266
|
-
|
285
|
+
from_format="pdb-0",
|
286
|
+
conversion_kwargs={"strict": True},
|
267
287
|
expect_success=False,
|
268
288
|
callback=MCB(CheckFileStatus(expect_output_exists=False,
|
269
289
|
expect_log_exists=None),
|
@@ -278,7 +298,8 @@ l_all_test_specs.append(Spec(name="Blocked conversion - wrong input type",
|
|
278
298
|
l_all_test_specs.append(Spec(name="Failed conversion - wrong input type",
|
279
299
|
filename="1NE6.mmcif",
|
280
300
|
to_format="cif",
|
281
|
-
|
301
|
+
from_format="pdb-0",
|
302
|
+
conversion_kwargs={"strict": False},
|
282
303
|
expect_success=False,
|
283
304
|
callback=MCB(CheckFileStatus(expect_output_exists=False,
|
284
305
|
expect_log_exists=None),
|
@@ -291,6 +312,8 @@ l_all_test_specs.append(Spec(name="Large files - Library and CLA",
|
|
291
312
|
filename=["ch3cl-esp.cub", "benzyne.molden", "periodic_dmol3.outmol",
|
292
313
|
"fullRhinovirus.pdb"],
|
293
314
|
to_format=["cdjson", "dmol", "mol", "cif"],
|
315
|
+
from_format=[None, None, None, "pdb-0"],
|
316
|
+
conversion_kwargs=[{}, {}, {}, {"strict": False}],
|
294
317
|
converter_name=[CONVERTER_OB, CONVERTER_OB, CONVERTER_OB, CONVERTER_C2X],
|
295
318
|
callback=CheckFileStatus(),
|
296
319
|
compatible_with_gui=False,
|
@@ -301,6 +324,7 @@ l_all_test_specs.append(Spec(name="Large files - GUI",
|
|
301
324
|
filename=["ch3cl-esp.cub", "benzyne.molden",
|
302
325
|
"periodic_dmol3.outmol", "fullRhinovirus.pdb"],
|
303
326
|
to_format=["cdjson", "dmol", "mol", "cif"],
|
327
|
+
from_format=[None, None, None, "pdb-0"],
|
304
328
|
converter_name=[CONVERTER_OB, CONVERTER_OB, CONVERTER_OB, CONVERTER_C2X],
|
305
329
|
expect_success=[False, False, False, True],
|
306
330
|
callback=[CheckException(ex_type=FileConverterInputException),
|
@@ -319,7 +343,7 @@ max_size_callback = MCB(CheckFileStatus(expect_output_exists=False),
|
|
319
343
|
ex_status_code=const.STATUS_CODE_SIZE))
|
320
344
|
l_all_test_specs.append(Spec(name="Max size exceeded",
|
321
345
|
filename=["1NE6.mmcif", "caffeine-smi.tar.gz"],
|
322
|
-
to_format="pdb",
|
346
|
+
to_format="pdb-0",
|
323
347
|
conversion_kwargs=[{"max_file_size": 0.0001}, {"max_file_size": 0.0005}],
|
324
348
|
expect_success=False,
|
325
349
|
callback=max_size_callback,
|