chore(lib): use pathlib.Path instead of str (#133)

* wip(lib): change os.path to pathlib.Path

* chore(lib): use pathlib.Path instead of str

* fix(logger): convert Path to str

* chore(lint): add type hint to prevent future errors

* fix(lib): correct suffix addition
This commit is contained in:
Jérome Eertmans
2023-02-25 17:21:50 +01:00
committed by GitHub
parent 4cd433b35a
commit dc1be25e6e
4 changed files with 70 additions and 84 deletions

View File

@ -4,24 +4,25 @@ import shutil
import subprocess
import tempfile
from enum import Enum
from typing import Callable, Dict, List, Optional, Set, Union
from pathlib import Path
from typing import Dict, List, Optional, Set, Union
from pydantic import BaseModel, root_validator, validator
from pydantic import BaseModel, FilePath, root_validator, validator
from PySide6.QtCore import Qt
from .manim import FFMPEG_BIN, logger
def merge_basenames(files: List[str]) -> str:
def merge_basenames(files: List[FilePath]) -> Path:
"""
Merge multiple filenames by concatenating basenames.
"""
logger.info(f"Generating a new filename for animations: {files}")
dirname = os.path.dirname(files[0])
_, ext = os.path.splitext(files[0])
dirname = files[0].parent
ext = files[0].suffix
basenames = (os.path.splitext(os.path.basename(file))[0] for file in files)
basenames = (file.stem for file in files)
basenames_str = ",".join(f"{len(b)}:{b}" for b in basenames)
@ -29,7 +30,7 @@ def merge_basenames(files: List[str]) -> str:
# https://github.com/jeertmans/manim-slides/issues/123
basename = hashlib.sha256(basenames_str.encode()).hexdigest()
return os.path.join(dirname, basename + ext)
return dirname / (basename + ext)
class Key(BaseModel): # type: ignore
@ -146,24 +147,12 @@ class SlideConfig(BaseModel): # type: ignore
class PresentationConfig(BaseModel): # type: ignore
slides: List[SlideConfig]
files: List[str]
@validator("files", pre=True, each_item=True)
def is_file_and_exists(cls, v: str) -> str:
if not os.path.exists(v):
raise ValueError(
f"Animation file {v} does not exist. Are you in the right directory?"
)
if not os.path.isfile(v):
raise ValueError(f"Animation file {v} is not a file")
return v
files: List[FilePath]
@root_validator
def animation_indices_match_files(
cls, values: Dict[str, Union[List[SlideConfig], List[str]]]
) -> Dict[str, Union[List[SlideConfig], List[str]]]:
cls, values: Dict[str, Union[List[SlideConfig], List[FilePath]]]
) -> Dict[str, Union[List[SlideConfig], List[FilePath]]]:
files = values.get("files")
slides = values.get("slides")
@ -180,26 +169,21 @@ class PresentationConfig(BaseModel): # type: ignore
return values
def move_to(self, dest: str, copy: bool = True) -> "PresentationConfig":
def copy_to(self, dest: Path) -> "PresentationConfig":
"""
Moves (or copy) the files to a given directory.
Copy the files to a given directory.
"""
copy_func: Callable[[str, str], None] = shutil.copy
move_func: Callable[[str, str], None] = shutil.move
move = copy_func if copy else move_func
n = len(self.files)
for i in range(n):
file = self.files[i]
basename = os.path.basename(file)
dest_path = os.path.join(dest, basename)
dest_path = dest / self.files[i].name
logger.debug(f"Moving / copying {file} to {dest_path}")
move(file, dest_path)
shutil.copy(file, dest_path)
self.files[i] = dest_path
return self
def concat_animations(self, dest: Optional[str] = None) -> "PresentationConfig":
def concat_animations(self, dest: Optional[Path] = None) -> "PresentationConfig":
"""
Concatenate animations such that each slide contains one animation.
"""
@ -216,7 +200,7 @@ class PresentationConfig(BaseModel): # type: ignore
f.writelines(f"file '{os.path.abspath(path)}'\n" for path in files)
f.close()
command = [
command: List[str] = [
FFMPEG_BIN,
"-f",
"concat",
@ -226,7 +210,7 @@ class PresentationConfig(BaseModel): # type: ignore
f.name,
"-c",
"copy",
dest_path,
str(dest_path),
"-y",
]
logger.debug(" ".join(command))
@ -252,7 +236,7 @@ class PresentationConfig(BaseModel): # type: ignore
self.files = dest_paths
if dest:
return self.move_to(dest)
return self.copy_to(dest)
return self