-
Notifications
You must be signed in to change notification settings - Fork 1
/
core.py
105 lines (84 loc) · 3.3 KB
/
core.py
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
__all__ = ['Information']
import collections as c
import os
import pathlib as p
import typing as t
from ...base import Foam, Path
if t.TYPE_CHECKING:
from ..command import Command
class Information:
'''OpenFOAM information wrapper'''
Self = __qualname__
def __init__(self, foam: t.Optional[Foam]) -> None:
self._foam = foam
self._cmd = None
@classmethod
def from_foam(cls, foam: Foam) -> Self:
return cls(foam)
@classmethod
def from_nothing(cls) -> Self:
return cls(None)
@property
def cmd(self) -> 'Command':
'''Command without asserting (no need to call `Foam::save` method first)'''
assert self._foam is not None
from ..command import Command
if self._cmd is None:
self._cmd = Command.from_foam_without_asserting(self._foam)
return self._cmd
@property
def environ(self) -> t.Dict[str, str]:
'''OpenFOAM environments (aliase for `Foam::environ` property)'''
if self._foam is not None:
return self._foam.environ
else:
return {
key: value
for key, value in os.environ.items()
if key.startswith('FOAM')
}
@property
def root(self) -> p.Path:
return p.Path(self.environ['FOAM_TUTORIALS']).parent
def search(self, *targets: str, process: bool = True) -> t.Union[str, t.Set[str]]:
'''`foamSearch` wrapper
- Reference:
- https://github.com/OpenFOAM/OpenFOAM-7/blob/master/bin/foamSearch
- https://github.com/OpenFOAM/OpenFOAM-7/blob/master/applications/utilities/miscellaneous/foamDictionary/foamDictionary.C
'''
assert len(targets) > 1
fields = '.'.join(map(lambda string: string.replace(' ', ''), targets[1:]))
command = f'foamSearch {self.environ["FOAM_TUTORIALS"]} {targets[0]} "{fields}"'
stdout = self.cmd.raw(command, output=True).stdout.decode()
if not process:
return stdout
try:
return set(
line.split(' ', maxsplit=1)[-1].strip()
for line in stdout.splitlines()
)
except:
return stdout
def search_yaml(self, *targets: str, root: Path = '.') -> t.Dict[t.Hashable, t.Set[str]]:
'''`foamSearch` in YAML
- Note:
- `targets` should be as detailed as possible, as it is assumed that `targets` will only appear once in a file
'''
assert targets
record = c.defaultdict(set)
hashing = lambda string: string.lower().replace(' ', '')
hashed_targets = tuple(map(hashing, targets))
length = len(targets)
for path in p.Path(root).rglob('*'):
if path.suffix in {'.yaml', '.yml'}:
# try-except or try-except-else?
try:
foam = Foam.from_file(path)
except: # TODO: catch ConstructorError only
continue
for keys, _ in foam['foam'].items(with_list=False):
hashed_keys = tuple(map(hashing, keys))
if hashed_keys[-length:] == hashed_targets:
record[foam['foam'][keys]].add(path.absolute().as_posix())
break
return dict(record)