-
Notifications
You must be signed in to change notification settings - Fork 7
Expand file tree
/
Copy path_helpers.py
More file actions
132 lines (113 loc) · 3.74 KB
/
Copy path_helpers.py
File metadata and controls
132 lines (113 loc) · 3.74 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
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
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
import logging
import os
import shutil
from pathlib import Path
from zipfile import BadZipFile, ZipFile
from bs4 import BeautifulSoup
logger = logging.getLogger(__name__)
def extract_ork_from_zip(zip_path: Path, extract_dir: Path) -> Path:
"""Extracts .ork file from a zip archive and returns its path.
This is important because sometimes the .xml file is stuck inside the .ork
file. The function extracts the .ork (.xml) file from the zip (.ork) file
and returns its path as a Path object.
Notes
-----
For illustration: if you try to open the .ork file with a text editor and
you see a bunch of weird characters, it is probably a "zip" file. You can
try to rename the file to .zip and open it with a zip extractor.
Parameters
----------
zip_path : Path
The path to the .zip file.
extract_dir : Path
The path to the directory where the .ork file will be extracted.
Returns
-------
Path
The path to the extracted .ork file.
"""
try:
temp_zip_path = zip_path.with_suffix(".zip")
shutil.copy(zip_path, temp_zip_path)
with ZipFile(temp_zip_path) as zf:
zf.extract("rocket.ork", path=extract_dir)
logger.info(
'Successfully extracted rocket.ork from "%s" to "%s"',
zip_path.as_posix(),
extract_dir.as_posix(),
)
return extract_dir / "rocket.ork"
except BadZipFile:
logger.warning(
'The file "%s" seems to be a rocket.ork file and not a compressed archive.',
zip_path.as_posix(),
)
return zip_path
except Exception as e:
logger.error(
'Error while extracting data from "%s": %s', zip_path.as_posix(), e
)
raise
finally:
if temp_zip_path.exists():
os.remove(temp_zip_path)
def parse_ork_file(ork_path: Path):
"""Parses the .ork file and returns BeautifulSoup and a list of datapoints.
Parameters
----------
ork_path : Path
The path to the .ork file.
Returns
-------
BeautifulSoup
The BeautifulSoup object.
"""
try:
with open(ork_path, encoding="utf-8") as file:
bs = BeautifulSoup(file, features="xml")
datapoints = bs.find_all("datapoint")
logger.info(
"Successfully parsed .ork file at '%s' with %d datapoints",
ork_path.as_posix(),
len(datapoints),
)
return bs, datapoints
except UnicodeDecodeError as exc:
error_msg = (
"The .ork file is not in UTF-8."
+ "Please open the .ork file in a text editor and save it as UTF-8."
)
logger.error(error_msg)
raise UnicodeDecodeError(error_msg) from exc
except Exception as e:
logger.error("Error while parsing the file '%s': %s", ork_path.as_posix(), e)
raise e
def _dict_to_string(dictionary, indent=0):
"""Converts a dictionary to a string.
Parameters
----------
dictionary : dict
Dictionary to be converted.
indent : int, optional
Indentation level, by default 0.
Returns
-------
str
String representation of the dictionary.
Examples
--------
>>> from rocketserializer._helpers import _dict_to_string
>>> _dict_to_string({"a": 1, "b": {"c": 2}})
" a: 1\n b: \n c: 2\n"
"""
string = ""
for key, value in dictionary.items():
string += " " * indent + str(key) + ": "
if isinstance(value, dict):
string += "\n" + _dict_to_string(value, indent + 4)
else:
string += str(value) + "\n"
return string
# if __name__ == "__main__":
# import doctest
# doctest.testmod()