1 | import json |
---|
2 | import warnings |
---|
3 | |
---|
4 | from framsfiles._context import _contexts |
---|
5 | from ._parser import _parse_object_list, _parse_object |
---|
6 | |
---|
7 | _NO_FILE_EXTENSION_WARNING = 'No file extension found. Setting default context.' |
---|
8 | _UNSUPPORTED_EXTENSION_WARNING = 'Unsupported file extension: \'{}\'. Setting default context.' |
---|
9 | _UNSUPPORTED_CONTEXT_WARNING = 'Unsupported context: "{}". Setting default context.' |
---|
10 | |
---|
11 | _INVALID_ROOT_ERROR = 'JSON root should be an object or a list, found: {}. Aborting.' |
---|
12 | |
---|
13 | |
---|
14 | def from_file(filename, context=None): |
---|
15 | """ |
---|
16 | Converts the file with a given filename to Framsticks file format. |
---|
17 | :param filename: Name of the file to parse. |
---|
18 | :param context: Context of parsing compliant with contexts found in 'framscript.xml' e.g. 'expdef file'. |
---|
19 | If context is left empty it will be inferred from the file's extension. |
---|
20 | :return: String content of equivalent Framsticks file. |
---|
21 | """ |
---|
22 | if context is None: |
---|
23 | context = _get_context_from_filename(filename) |
---|
24 | with open(filename, encoding='UTF-8') as file: |
---|
25 | json_object = json.load(file) |
---|
26 | return from_collection(json_object, context) |
---|
27 | |
---|
28 | |
---|
29 | def from_collection(target, context=None): |
---|
30 | """ |
---|
31 | Converts a list or a dictionary to Framsticks file format. |
---|
32 | :param target: Dictionary or list of dictionaries representing Framsticks objects. |
---|
33 | :param context: Context of parsing compliant with contexts found in 'framscript.xml' |
---|
34 | :return: String content of resulting Framsticks file. |
---|
35 | """ |
---|
36 | if context is not None and context not in _contexts: |
---|
37 | warnings.warn(_UNSUPPORTED_CONTEXT_WARNING.format(context)) |
---|
38 | if isinstance(target, list): |
---|
39 | return _parse_object_list(target, context) |
---|
40 | if isinstance(target, dict): |
---|
41 | return _parse_object(target, context) |
---|
42 | raise ValueError(_INVALID_ROOT_ERROR.format(type(target))) |
---|
43 | |
---|
44 | |
---|
45 | def _get_context_from_filename(filename): |
---|
46 | filename_split = filename.split('.') |
---|
47 | if len(filename_split) < 2: |
---|
48 | warnings.warn(_NO_FILE_EXTENSION_WARNING) |
---|
49 | return None |
---|
50 | |
---|
51 | extension = filename_split[-2] |
---|
52 | filename_context = extension + ' file' |
---|
53 | if filename_context not in _contexts: |
---|
54 | warnings.warn(_UNSUPPORTED_EXTENSION_WARNING.format(filename_context)) |
---|
55 | return None |
---|
56 | |
---|
57 | return filename_context |
---|