Source code for megu.utils
# -*- encoding: utf-8 -*-
# Copyright (c) 2021 Stephen Bunn <stephen@bunn.io>
# GPLv3 License <https://choosealicense.com/licenses/gpl-3.0/>
"""Contains utilities for the framework to use.
These helper/utility functions should **not** be exposed to plugins.
"""
import functools
from pathlib import Path
from typing import Callable, TypeVar
from .config import instance as config
from .log import instance as log
REQUIRED_DIRECTORIES = (
config.cache_dir,
config.log_dir,
config.plugin_dir,
config.temp_dir,
)
_T = TypeVar("_T")
[docs]def compose_functions(*functions: Callable[[_T], _T]) -> Callable[[_T], _T]:
"""Compose many similar functions together.
Args:
functions (List[Callable[[_T], _T]]):
Many functions to compose together.
Returns:
Callable[[_T], _T]:
A new function that applies all provided functions in order.
"""
return functools.reduce(
lambda func_1, func_2: lambda x: func_2(func_1(x)),
functions,
lambda x: x,
)
[docs]def create_required_directories():
"""Handle setting up the required directories on the local machine."""
for required_dirpath in REQUIRED_DIRECTORIES:
if not required_dirpath.is_dir():
log.debug(f"Creating required directory at {required_dirpath}")
required_dirpath.mkdir(mode=0o777, parents=True)
[docs]def allocate_storage(to_path: Path, size: int) -> Path:
"""Allocate a specific number of bytes to a non-existing filepath.
Args:
to_path (~pathlib.Path):
The filepath to allocate a specific number of bytes to.
size (int):
The number of bytes to allocate.
Raises:
FileExistsError:
If the given filepath already exists
Returns:
~pathlib.Path: The given filepath
"""
if size <= 0:
raise ValueError(f"Expected byte size > 0 to allocate, received {size!s}")
if to_path.exists():
raise FileExistsError(f"File at {to_path!s} already exists")
if not to_path.parent.is_dir():
log.debug(f"Creating directory {to_path.parent!s} to allocate {to_path!s}")
to_path.parent.mkdir(mode=0o777, parents=True)
log.debug(f"Allocating {size!s} bytes at {to_path!s}")
with to_path.open("wb") as file_handle:
file_handle.seek(size - 1)
file_handle.write(b"\x00")
return to_path