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