Path:
strictdoc/backend/sdoc/pickle_cache.py
Lines:
86
Non-empty lines:
75
Non-empty lines covered with requirements:
75 / 75 (100.0%)
Functions:
4
Functions covered by requirements:
4 / 4 (100.0%)
1
"""2
@relation(SDOC-SRS-95, scope=file)3
"""4
5
import hashlib
6
import os
7
from pathlib import Path
8
from typing import Any
9
10
from strictdoc.core.project_config import ProjectConfig
11
from strictdoc.helpers.md5 import get_file_md5
12
from strictdoc.helpers.pickle import pickle_dump, pickle_load
13
14
15
class PickleCache:
16
@staticmethod17
def read_from_cache(
18
file_path: str, project_config: ProjectConfig, content_kind: str
19
) -> Any:
20
path_to_cached_file: str = PickleCache.get_cached_file_path(
21
file_path, project_config, content_kind
22
)23
if os.path.isfile(path_to_cached_file):
24
with open(path_to_cached_file, "rb") as cache_file:
25
unpickled_content = cache_file.read()
26
try:
27
return pickle_load(unpickled_content)
28
except Exception as exception_:
29
raise AssertionError(
30
"MUST NOT REACH HERE: "31
f"Error when unpickling a cache file: {path_to_cached_file}. "
32
"To fix the issue, simply remove the cache file or the whole cache folder. "33
"Please report this exception to StrictDoc developers: "34
f"https://github.com/strictdoc-project/strictdoc/issues/new"
35
) from exception_
36
return None
37
38
@staticmethod39
def save_to_cache(
40
content: Any,
41
file_path: str,
42
project_config: ProjectConfig,
43
content_kind: str,
44
) -> None:
45
path_to_cached_file: str = PickleCache.get_cached_file_path(
46
file_path, project_config, content_kind
47
)48
path_to_cached_file_dir: str = os.path.dirname(path_to_cached_file)
49
Path(path_to_cached_file_dir).mkdir(parents=True, exist_ok=True)
50
pickled_content: Any = pickle_dump(content)
51
with open(path_to_cached_file, "wb") as cache_file:
52
cache_file.write(pickled_content)
53
54
@staticmethod55
def get_cached_file_path(
56
file_path: str, project_config: ProjectConfig, content_kind: str
57
) -> str:
58
path_to_tmp_dir = project_config.get_path_to_cache_dir()
59
60
full_path_to_file = (
61
file_path62
if os.path.isabs(file_path)
63
else os.path.abspath(file_path)
64
)65
66
file_md5: str = get_file_md5(file_path)
67
68
# File name contains an MD5 hash of its full path to ensure the69
# uniqueness of the cached items. Additionally, the unique file name70
# contains a full path to the output root to prevent collisions71
# between StrictDoc invocations running against the same set of SDoc72
# files in parallel.73
unique_identifier = project_config.output_dir + full_path_to_file
74
unique_identifier_md5 = hashlib.md5(
75
unique_identifier.encode("utf-8")
76
).hexdigest()
77
file_name = os.path.basename(full_path_to_file)
78
file_name += "_" + unique_identifier_md5 + "_" + file_md5
79
80
path_to_cached_file = os.path.join(
81
path_to_tmp_dir,
82
content_kind,
83
file_name,
84
)85
86
return path_to_cached_file