Coverage for liitos / placeholder.py: 92.39%
70 statements
« prev ^ index » next coverage.py v7.13.2, created at 2026-02-03 22:54:48 +00:00
« prev ^ index » next coverage.py v7.13.2, created at 2026-02-03 22:54:48 +00:00
1"""Loader function for placeholders (mostly images)."""
3import pathlib
4import pkgutil
6from liitos import ENCODING, PathLike, log
8RESOURCES = (
9 'placeholders/this-resource-is-missing.jpg',
10 'placeholders/this-resource-is-missing.pdf',
11 'placeholders/this-resource-is-missing.png',
12 'placeholders/this-resource-is-missing.svg',
13 'placeholders/this-resource-is-missing.tiff',
14 'placeholders/this-resource-is-missing.webp',
15)
17READING_OPTIONS: dict[str, dict[str, list[str] | dict[str, str] | None]] = {
18 '.jpg': {'args': ['rb'], 'kwargs': None},
19 '.pdf': {'args': ['rb'], 'kwargs': None},
20 '.png': {'args': ['rb'], 'kwargs': None},
21 '.svg': {'args': ['rt'], 'kwargs': {'encoding': ENCODING}},
22 '.tiff': {'args': ['rb'], 'kwargs': None},
23 '.webp': {'args': ['rb'], 'kwargs': None},
24}
26WRITING_OPTIONS: dict[str, dict[str, list[str] | dict[str, str] | None]] = {
27 '.jpg': {'args': ['wb'], 'kwargs': None},
28 '.pdf': {'args': ['wb'], 'kwargs': None},
29 '.png': {'args': ['wb'], 'kwargs': None},
30 '.svg': {'args': ['wt'], 'kwargs': {'encoding': ENCODING}},
31 '.tiff': {'args': ['wb'], 'kwargs': None},
32 '.webp': {'args': ['wb'], 'kwargs': None},
33}
36def load_resource(resource: PathLike, is_complete_path: bool = False) -> tuple[str, bytes | str]:
37 """Load the template either from the package resources or an external path."""
38 from_path = pathlib.Path(resource)
39 suffix = from_path.suffix
40 if is_complete_path:
41 if suffix and suffix in READING_OPTIONS:
42 args = READING_OPTIONS[suffix].get('args')
43 kwargs = READING_OPTIONS[suffix].get('kwargs')
44 if READING_OPTIONS[suffix].get('kwargs'): 44 ↛ 47line 44 didn't jump to line 47 because the condition on line 44 was always true
45 with open(from_path, *args, **kwargs) as handle: # type: ignore
46 return 'str', handle.read()
47 with open(from_path, *args) as handle: # type: ignore
48 return 'bytes', handle.read()
49 with open(from_path, 'rb') as handle:
50 return 'bytes', handle.read()
52 if suffix and suffix in READING_OPTIONS: 52 ↛ 59line 52 didn't jump to line 59 because the condition on line 52 was always true
53 args = READING_OPTIONS[suffix].get('args')
54 kwargs = READING_OPTIONS[suffix].get('kwargs')
55 if READING_OPTIONS[suffix].get('kwargs'):
56 return 'str', pkgutil.get_data(__package__, str(resource)).decode(**kwargs) # type: ignore
57 return 'bytes', pkgutil.get_data(__package__, str(resource)) # type: ignore
59 return 'bytes', pkgutil.get_data(__package__, str(resource)) # type: ignore
62def eject(argv: list[str] | None = None) -> int:
63 """Eject the templates into the folder given (default MISSING) and create the folder if it does not exist."""
64 argv = argv if argv else ['']
65 into = argv[0]
66 if not into.strip():
67 into = 'MISSING'
68 into_path = pathlib.Path(into)
69 (into_path / 'placeholders').mkdir(parents=True, exist_ok=True)
70 for resource in RESOURCES:
71 write_to = into_path / resource
72 suffix = write_to.suffix
73 log.info(f'{resource} -> {write_to}')
74 if suffix and suffix in WRITING_OPTIONS: 74 ↛ 88line 74 didn't jump to line 88 because the condition on line 74 was always true
75 args = WRITING_OPTIONS[suffix].get('args')
76 kwargs = WRITING_OPTIONS[suffix].get('kwargs')
77 if WRITING_OPTIONS[suffix].get('kwargs'):
78 log.info(f'text({resource}) per ({args=}) and ({kwargs=})')
79 data = pkgutil.get_data(__package__, resource).decode(**kwargs) # type: ignore
80 with open(write_to, *args, **kwargs) as target: # type: ignore
81 target.write(data)
82 continue
83 log.info(f'binary({resource}) per ({args=})')
84 data = pkgutil.get_data(__package__, resource)
85 with open(write_to, *args) as target: # type: ignore
86 target.write(data) # type: ignore
87 continue
88 log.warning(f'suffix ({suffix}) empty or not in ({", ".join(WRITING_OPTIONS.keys())})')
90 return 0
93def dump_placeholder(target: PathLike) -> tuple[int, str]:
94 """Write out the placeholder matching the file type per suffix."""
95 suffix = pathlib.Path(target).suffix
96 proof = f'matching suffix ({suffix}) derived from target({target})'
97 if suffix in WRITING_OPTIONS:
98 args = WRITING_OPTIONS[suffix].get('args')
99 kwargs = WRITING_OPTIONS[suffix].get('kwargs')
100 resource = [res for res in RESOURCES if res.endswith(suffix)][0]
101 kind, data = load_resource(resource)
102 if kind == 'str':
103 with open(target, *args, **kwargs) as handle: # type: ignore
104 handle.write(data) # type: ignore
105 return 0, f'wrote text mode placeholder {proof}'
106 with open(target, *args) as handle: # type: ignore
107 handle.write(data) # type: ignore
108 return 0, f'wrote binary mode placeholder {proof}'
110 return 1, f'no placeholder found {proof}'