chore(lib): remove all os.path in favor to pathlib (#225)

* chore(lib): remove all os.path in favor to pathlib

* fix(lib): str to path
This commit is contained in:
Jérome Eertmans
2023-07-24 15:53:30 +02:00
committed by GitHub
parent a7719dbb8b
commit 88bffe0f0b
5 changed files with 54 additions and 53 deletions

View File

@ -1,6 +1,5 @@
import hashlib import hashlib
import json import json
import os
import shutil import shutil
import subprocess import subprocess
import tempfile import tempfile
@ -261,11 +260,11 @@ class PresentationConfig(BaseModel): # type: ignore
continue continue
f = tempfile.NamedTemporaryFile(mode="w", delete=False) f = tempfile.NamedTemporaryFile(mode="w", delete=False)
f.writelines(f"file '{os.path.abspath(path)}'\n" for path in files) f.writelines(f"file '{path.absolute()}'\n" for path in files)
f.close() f.close()
command: List[str] = [ command: List[str] = [
FFMPEG_BIN, str(FFMPEG_BIN),
"-f", "-f",
"concat", "concat",
"-safe", "-safe",

View File

@ -1,3 +1,5 @@
FOLDER_PATH: str = "./slides" from pathlib import Path
CONFIG_PATH: str = ".manim-slides.toml"
FFMPEG_BIN: str = "ffmpeg" FOLDER_PATH: Path = Path("./slides")
CONFIG_PATH: Path = Path(".manim-slides.toml")
FFMPEG_BIN: Path = Path("ffmpeg")

View File

@ -76,7 +76,7 @@ class Presentation:
self.__current_slide_index: int = 0 self.__current_slide_index: int = 0
self.current_animation: int = self.current_slide.start_animation self.current_animation: int = self.current_slide.start_animation
self.current_file: str = "" self.current_file: Path = Path("")
self.loaded_animation_cap: int = -1 self.loaded_animation_cap: int = -1
self.cap = None # cap = cv2.VideoCapture self.cap = None # cap = cv2.VideoCapture
@ -185,10 +185,10 @@ class Presentation:
self.release_cap() self.release_cap()
file: str = str(self.files[animation]) file: Path = self.files[animation]
if self.reverse: if self.reverse:
file = "{}_reversed{}".format(*os.path.splitext(file)) file = file.parent / f"{file.stem}_reversed{file.suffix}"
self.reversed_animation = animation self.reversed_animation = animation
self.current_file = file self.current_file = file
@ -371,7 +371,7 @@ class Display(QThread): # type: ignore
self.config = config self.config = config
self.skip_all = skip_all self.skip_all = skip_all
self.record_to = record_to self.record_to = record_to
self.recordings: List[Tuple[str, int, int]] = [] self.recordings: List[Tuple[Path, int, int]] = []
self.state = State.PLAYING self.state = State.PLAYING
self.lastframe: Optional[np.ndarray] = None self.lastframe: Optional[np.ndarray] = None
@ -480,7 +480,7 @@ class Display(QThread): # type: ignore
) )
file, frame_number, fps = self.recordings[0] file, frame_number, fps = self.recordings[0]
cap = cv2.VideoCapture(file) cap = cv2.VideoCapture(str(file))
cap.set(cv2.CAP_PROP_POS_FRAMES, frame_number - 1) cap.set(cv2.CAP_PROP_POS_FRAMES, frame_number - 1)
_, frame = cap.read() _, frame = cap.read()
@ -496,7 +496,7 @@ class Display(QThread): # type: ignore
if file != _file: if file != _file:
cap.release() cap.release()
file = _file file = _file
cap = cv2.VideoCapture(_file) cap = cv2.VideoCapture(str(_file))
cap.set(cv2.CAP_PROP_POS_FRAMES, frame_number - 1) cap.set(cv2.CAP_PROP_POS_FRAMES, frame_number - 1)
_, frame = cap.read() _, frame = cap.read()

View File

@ -1,7 +1,7 @@
import os
import platform import platform
import shutil import shutil
import subprocess import subprocess
from pathlib import Path
from typing import ( from typing import (
Any, Any,
List, List,
@ -9,6 +9,7 @@ from typing import (
MutableMapping, MutableMapping,
Optional, Optional,
Sequence, Sequence,
Set,
Tuple, Tuple,
ValuesView, ValuesView,
) )
@ -34,9 +35,9 @@ from .manim import (
) )
def reverse_video_file(src: str, dst: str) -> None: def reverse_video_file(src: Path, dst: Path) -> None:
"""Reverses a video file, writting the result to `dst`.""" """Reverses a video file, writting the result to `dst`."""
command = [FFMPEG_BIN, "-i", src, "-vf", "reverse", dst] command = [str(FFMPEG_BIN), "-i", str(src), "-vf", "reverse", str(dst)]
logger.debug(" ".join(command)) logger.debug(" ".join(command))
process = subprocess.Popen(command, stdout=subprocess.PIPE, stderr=subprocess.PIPE) process = subprocess.Popen(command, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
output, error = process.communicate() output, error = process.communicate()
@ -54,11 +55,10 @@ class Slide(Scene): # type:ignore
""" """
def __init__( def __init__(
self, *args: Any, output_folder: str = FOLDER_PATH, **kwargs: Any self, *args: Any, output_folder: Path = FOLDER_PATH, **kwargs: Any
) -> None: ) -> None:
if MANIMGL: if MANIMGL:
if not os.path.isdir("videos"): Path("videos").mkdir(exist_ok=True)
os.mkdir("videos")
kwargs["file_writer_config"] = { kwargs["file_writer_config"] = {
"break_into_partial_movies": True, "break_into_partial_movies": True,
"output_directory": "", "output_directory": "",
@ -69,7 +69,7 @@ class Slide(Scene): # type:ignore
super().__init__(*args, **kwargs) super().__init__(*args, **kwargs)
self.__output_folder = output_folder self.__output_folder: Path = output_folder
self.__slides: List[SlideConfig] = [] self.__slides: List[SlideConfig] = []
self.__current_slide = 1 self.__current_slide = 1
self.__current_animation = 0 self.__current_animation = 0
@ -111,7 +111,7 @@ class Slide(Scene): # type:ignore
return config["pixel_width"], config["pixel_height"] return config["pixel_width"], config["pixel_height"]
@property @property
def __partial_movie_files(self) -> List[str]: def __partial_movie_files(self) -> List[Path]:
"""Returns a list of partial movie files, a.k.a animations.""" """Returns a list of partial movie files, a.k.a animations."""
if MANIMGL: if MANIMGL:
from manimlib.utils.file_ops import get_sorted_integer_files from manimlib.utils.file_ops import get_sorted_integer_files
@ -120,11 +120,13 @@ class Slide(Scene): # type:ignore
"remove_non_integer_files": True, "remove_non_integer_files": True,
"extension": self.file_writer.movie_file_extension, "extension": self.file_writer.movie_file_extension,
} }
return get_sorted_integer_files( # type: ignore files = get_sorted_integer_files(
self.file_writer.partial_movie_directory, **kwargs self.file_writer.partial_movie_directory, **kwargs
) )
else: else:
return self.renderer.file_writer.partial_movie_files # type: ignore files = self.renderer.file_writer.partial_movie_files
return [Path(file) for file in files]
@property @property
def __show_progress_bar(self) -> bool: def __show_progress_bar(self) -> bool:
@ -470,25 +472,23 @@ class Slide(Scene): # type:ignore
""" """
self.__add_last_slide() self.__add_last_slide()
if not os.path.exists(self.__output_folder): self.__output_folder.mkdir(parents=True, exist_ok=True)
os.mkdir(self.__output_folder)
files_folder = os.path.join(self.__output_folder, "files") files_folder = self.__output_folder / "files"
if not os.path.exists(files_folder): files_folder.mkdir(exist_ok=True)
os.mkdir(files_folder)
scene_name = str(self) scene_name = str(self)
scene_files_folder = os.path.join(files_folder, scene_name) scene_files_folder = files_folder / scene_name
old_animation_files = set() old_animation_files: Set[Path] = set()
if not os.path.exists(scene_files_folder): if not scene_files_folder.exists():
os.mkdir(scene_files_folder) scene_files_folder.mkdir()
elif not use_cache: elif not use_cache:
shutil.rmtree(scene_files_folder) shutil.rmtree(scene_files_folder)
os.mkdir(scene_files_folder) scene_files_folder.mkdir()
else: else:
old_animation_files.update(os.listdir(scene_files_folder)) old_animation_files.update(scene_files_folder.iterdir())
files = [] files = []
for src_file in tqdm( for src_file in tqdm(
@ -504,10 +504,11 @@ class Slide(Scene): # type:ignore
# but animations before a will have a None src_file # but animations before a will have a None src_file
continue continue
filename = os.path.basename(src_file) filename = src_file.name
rev_filename = "{}_reversed{}".format(*os.path.splitext(filename)) rev_filename = (
src_file.parent / f"{src_file.stem}_reversed{src_file.suffix}"
dst_file = os.path.join(scene_files_folder, filename) )
dst_file = scene_files_folder / filename
# We only copy animation if it was not present # We only copy animation if it was not present
if filename in old_animation_files: if filename in old_animation_files:
old_animation_files.remove(filename) old_animation_files.remove(filename)
@ -518,7 +519,7 @@ class Slide(Scene): # type:ignore
if rev_filename in old_animation_files: if rev_filename in old_animation_files:
old_animation_files.remove(rev_filename) old_animation_files.remove(rev_filename)
else: else:
rev_file = os.path.join(scene_files_folder, rev_filename) rev_file = scene_files_folder / rev_filename
reverse_video_file(src_file, rev_file) reverse_video_file(src_file, rev_file)
files.append(dst_file) files.append(dst_file)
@ -533,23 +534,20 @@ class Slide(Scene): # type:ignore
slide.end_animation -= offset slide.end_animation -= offset
logger.info( logger.info(
f"Copied {len(files)} animations to '{os.path.abspath(scene_files_folder)}' and generated reversed animations" f"Copied {len(files)} animations to '{scene_files_folder.absolute()}' and generated reversed animations"
) )
slide_path = os.path.join(self.__output_folder, "%s.json" % (scene_name,)) slide_path = self.__output_folder / f"{scene_name}.json"
with open(slide_path, "w") as f: PresentationConfig(
f.write( slides=self.__slides,
PresentationConfig( files=files,
slides=self.__slides, resolution=self.__resolution,
files=files, background_color=self.__background_color,
resolution=self.__resolution, ).to_file(slide_path)
background_color=self.__background_color,
).model_dump_json(indent=2)
)
logger.info( logger.info(
f"Slide '{scene_name}' configuration written in '{os.path.abspath(slide_path)}'" f"Slide '{scene_name}' configuration written in '{slide_path.absolute()}'"
) )
def run(self, *args: Any, **kwargs: Any) -> None: def run(self, *args: Any, **kwargs: Any) -> None:

View File

@ -1,13 +1,15 @@
from pathlib import Path
from manim_slides.defaults import CONFIG_PATH, FFMPEG_BIN, FOLDER_PATH from manim_slides.defaults import CONFIG_PATH, FFMPEG_BIN, FOLDER_PATH
def test_folder_path() -> None: def test_folder_path() -> None:
assert FOLDER_PATH == "./slides" assert FOLDER_PATH == Path("./slides")
def test_config_path() -> None: def test_config_path() -> None:
assert CONFIG_PATH == ".manim-slides.toml" assert CONFIG_PATH == Path(".manim-slides.toml")
def test_ffmpeg_bin() -> None: def test_ffmpeg_bin() -> None:
assert FFMPEG_BIN == "ffmpeg" assert FFMPEG_BIN == Path("ffmpeg")