mirror of
https://github.com/jeertmans/manim-slides.git
synced 2025-09-19 12:44:11 +08:00
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:
@ -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
|
||||
|
||||
|
Reference in New Issue
Block a user