mirror of
https://github.com/jeertmans/manim-slides.git
synced 2025-05-21 20:46:01 +08:00
chore(ci): pre-commit mypy (#41)
* chore(ci): pre-commit mypy * chore: ignore non-lib files * chore: ignore setup.py * [pre-commit.ci] pre-commit autoupdate (#47) updates: - [github.com/psf/black: 22.8.0 → 22.10.0](https://github.com/psf/black/compare/22.8.0...22.10.0) - [github.com/psf/black: 22.8.0 → 22.10.0](https://github.com/psf/black/compare/22.8.0...22.10.0) Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> * chore(ci): pre-commit mypy * chore: ignore non-lib files * chore: ignore setup.py * fix: update pre-commit config for mypy * feat: add some missing type hints Co-authored-by: Jérome Eertmans <jeertmans@icloud.com> Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
This commit is contained in:
@ -1,14 +1,29 @@
|
||||
import platform
|
||||
from typing import Tuple
|
||||
|
||||
import cv2
|
||||
|
||||
FONT_ARGS = (cv2.FONT_HERSHEY_SIMPLEX, 1, 255, 1, cv2.LINE_AA)
|
||||
__all__ = [
|
||||
"FONT_ARGS",
|
||||
"FOLDER_PATH",
|
||||
"CONFIG_PATH",
|
||||
"RIGHT_ARROW_KEY_CODE",
|
||||
"LEFT_ARROW_KEY_CODE",
|
||||
]
|
||||
|
||||
FONT_ARGS: Tuple[int, int, int, int, int] = (
|
||||
cv2.FONT_HERSHEY_SIMPLEX, # type: ignore
|
||||
1,
|
||||
255,
|
||||
1,
|
||||
cv2.LINE_AA, # type: ignore
|
||||
)
|
||||
FOLDER_PATH: str = "./slides"
|
||||
CONFIG_PATH: str = ".manim-slides.json"
|
||||
|
||||
if platform.system() == "Windows":
|
||||
RIGHT_ARROW_KEY_CODE = 2555904
|
||||
LEFT_ARROW_KEY_CODE = 2424832
|
||||
RIGHT_ARROW_KEY_CODE: int = 2555904
|
||||
LEFT_ARROW_KEY_CODE: int = 2424832
|
||||
elif platform.system() == "Darwin":
|
||||
RIGHT_ARROW_KEY_CODE = 63235
|
||||
LEFT_ARROW_KEY_CODE = 63234
|
||||
|
@ -21,7 +21,7 @@ __all__ = [
|
||||
|
||||
|
||||
@contextmanager
|
||||
def suppress_stdout():
|
||||
def suppress_stdout() -> None:
|
||||
with open(os.devnull, "w") as devnull:
|
||||
old_stdout = sys.stdout
|
||||
sys.stdout = devnull
|
||||
|
@ -56,7 +56,7 @@ def fix_time(t: float) -> float:
|
||||
class Presentation:
|
||||
"""Creates presentation from a configuration object."""
|
||||
|
||||
def __init__(self, config: PresentationConfig):
|
||||
def __init__(self, config: PresentationConfig) -> None:
|
||||
self.slides: List[SlideConfig] = config.slides
|
||||
self.files: List[str] = config.files
|
||||
|
||||
@ -90,14 +90,14 @@ class Presentation:
|
||||
"""Returns last slide."""
|
||||
return self.slides[-1]
|
||||
|
||||
def release_cap(self):
|
||||
def release_cap(self) -> None:
|
||||
"""Releases current Video Capture, if existing."""
|
||||
if self.cap is not None:
|
||||
self.cap.release()
|
||||
|
||||
self.loaded_animation_cap = -1
|
||||
|
||||
def load_animation_cap(self, animation: int):
|
||||
def load_animation_cap(self, animation: int) -> None:
|
||||
"""Loads video file of given animation."""
|
||||
# We must load a new VideoCapture file if:
|
||||
if (self.loaded_animation_cap != animation) or (
|
||||
@ -123,7 +123,7 @@ class Presentation:
|
||||
self.load_animation_cap(self.current_animation)
|
||||
return self.cap
|
||||
|
||||
def rewind_current_slide(self):
|
||||
def rewind_current_slide(self) -> None:
|
||||
"""Rewinds current slide to first frame."""
|
||||
if self.reverse:
|
||||
self.current_animation = self.current_slide.end_animation - 1
|
||||
@ -132,19 +132,19 @@ class Presentation:
|
||||
|
||||
self.current_cap.set(cv2.CAP_PROP_POS_FRAMES, 0)
|
||||
|
||||
def cancel_reverse(self):
|
||||
def cancel_reverse(self) -> None:
|
||||
"""Cancels any effet produced by a reversed slide."""
|
||||
if self.reverse:
|
||||
self.reverse = False
|
||||
self.reversed_animation = -1
|
||||
self.release_cap()
|
||||
|
||||
def reverse_current_slide(self):
|
||||
def reverse_current_slide(self) -> None:
|
||||
"""Reverses current slide."""
|
||||
self.reverse = True
|
||||
self.rewind_current_slide()
|
||||
|
||||
def load_next_slide(self):
|
||||
def load_next_slide(self) -> None:
|
||||
"""Loads next slide."""
|
||||
if self.reverse:
|
||||
self.cancel_reverse()
|
||||
@ -157,7 +157,7 @@ class Presentation:
|
||||
)
|
||||
self.rewind_current_slide()
|
||||
|
||||
def load_previous_slide(self):
|
||||
def load_previous_slide(self) -> None:
|
||||
"""Loads previous slide."""
|
||||
self.cancel_reverse()
|
||||
self.current_slide_index = max(0, self.current_slide_index - 1)
|
||||
@ -168,7 +168,7 @@ class Presentation:
|
||||
"""Returns the number of frames per second of the current video."""
|
||||
return self.current_cap.get(cv2.CAP_PROP_FPS)
|
||||
|
||||
def add_last_slide(self):
|
||||
def add_last_slide(self) -> None:
|
||||
"""Add a 'last' slide to the end of slides."""
|
||||
self.slides.append(
|
||||
SlideConfig(
|
||||
@ -179,14 +179,14 @@ class Presentation:
|
||||
)
|
||||
)
|
||||
|
||||
def reset(self):
|
||||
def reset(self) -> None:
|
||||
"""Rests current presentation."""
|
||||
self.current_animation = 0
|
||||
self.load_animation_cap(0)
|
||||
self.current_slide_index = 0
|
||||
self.slides[-1].terminated = False
|
||||
|
||||
def load_last_slide(self):
|
||||
def load_last_slide(self) -> None:
|
||||
"""Loads last slide."""
|
||||
self.current_slide_index = len(self.slides) - 2
|
||||
assert (
|
||||
@ -276,7 +276,7 @@ class Display:
|
||||
resolution=(1980, 1080),
|
||||
interpolation_flag=cv2.INTER_LINEAR,
|
||||
record_to=None,
|
||||
):
|
||||
) -> None:
|
||||
self.presentations = presentations
|
||||
self.start_paused = start_paused
|
||||
self.config = config
|
||||
@ -319,7 +319,7 @@ class Display:
|
||||
"""Returns the current presentation."""
|
||||
return self.presentations[self.current_presentation_index]
|
||||
|
||||
def run(self):
|
||||
def run(self) -> None:
|
||||
"""Runs a series of presentations until end or exit."""
|
||||
while not self.exit:
|
||||
self.lastframe, self.state = self.current_presentation.update_state(
|
||||
@ -342,7 +342,7 @@ class Display:
|
||||
self.show_video()
|
||||
self.show_info()
|
||||
|
||||
def show_video(self):
|
||||
def show_video(self) -> None:
|
||||
"""Shows updated video."""
|
||||
self.lag = now() - self.last_time
|
||||
self.last_time = now()
|
||||
@ -369,7 +369,7 @@ class Display:
|
||||
|
||||
cv2.imshow(WINDOW_NAME, frame)
|
||||
|
||||
def show_info(self):
|
||||
def show_info(self) -> None:
|
||||
"""Shows updated information about presentations."""
|
||||
info = np.zeros((130, 420), np.uint8)
|
||||
font_args = (FONT_ARGS[0], 0.7, *FONT_ARGS[2:])
|
||||
@ -406,7 +406,7 @@ class Display:
|
||||
|
||||
cv2.imshow(WINDOW_INFO_NAME, info)
|
||||
|
||||
def handle_key(self):
|
||||
def handle_key(self) -> None:
|
||||
"""Handles key strokes."""
|
||||
sleep_time = math.ceil(1000 / self.current_presentation.fps)
|
||||
key = cv2.waitKeyEx(fix_time(sleep_time - self.lag))
|
||||
@ -445,7 +445,7 @@ class Display:
|
||||
self.current_presentation.rewind_current_slide()
|
||||
self.state = State.PLAYING
|
||||
|
||||
def quit(self):
|
||||
def quit(self) -> None:
|
||||
"""Destroys all windows created by presentations and exits gracefully."""
|
||||
cv2.destroyAllWindows()
|
||||
|
||||
@ -489,7 +489,7 @@ class Display:
|
||||
show_default=True,
|
||||
)
|
||||
@click.help_option("-h", "--help")
|
||||
def list_scenes(folder):
|
||||
def list_scenes(folder) -> None:
|
||||
"""List available scenes."""
|
||||
|
||||
for i, scene in enumerate(_list_scenes(folder), start=1):
|
||||
@ -562,7 +562,7 @@ def present(
|
||||
resolution,
|
||||
interpolation_flag,
|
||||
record_to,
|
||||
):
|
||||
) -> None:
|
||||
"""
|
||||
Present SCENE(s), one at a time, in order.
|
||||
|
||||
@ -586,7 +586,7 @@ def present(
|
||||
click.echo("Choose number corresponding to desired scene/arguments.")
|
||||
click.echo("(Use comma separated list for multiple entries)")
|
||||
|
||||
def value_proc(value: str):
|
||||
def value_proc(value: str) -> List[str]:
|
||||
indices = list(map(int, value.strip().replace(" ", "").split(",")))
|
||||
|
||||
if not all(0 < i <= len(scene_choices) for i in indices):
|
||||
|
@ -11,7 +11,7 @@ from .defaults import FOLDER_PATH
|
||||
from .manim import FFMPEG_BIN, MANIMGL, Scene, ThreeDScene, config, logger
|
||||
|
||||
|
||||
def reverse_video_file(src: str, dst: str):
|
||||
def reverse_video_file(src: str, dst: str) -> None:
|
||||
"""Reverses a video file, writting the result to `dst`."""
|
||||
command = [FFMPEG_BIN, "-i", src, "-vf", "reverse", dst]
|
||||
process = subprocess.Popen(command, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
|
||||
@ -23,7 +23,7 @@ class Slide(Scene):
|
||||
Inherits from `manim.Scene` or `manimlib.Scene` and provide necessary tools for slides rendering.
|
||||
"""
|
||||
|
||||
def __init__(self, *args, output_folder=FOLDER_PATH, **kwargs):
|
||||
def __init__(self, *args, output_folder=FOLDER_PATH, **kwargs) -> None:
|
||||
if MANIMGL:
|
||||
if not os.path.isdir("videos"):
|
||||
os.mkdir("videos")
|
||||
@ -69,19 +69,19 @@ class Slide(Scene):
|
||||
return config["progress_bar"] != "none"
|
||||
|
||||
@property
|
||||
def leave_progress_bar(self):
|
||||
def leave_progress_bar(self) -> None:
|
||||
"""Returns True if progress bar should be left after completed."""
|
||||
if MANIMGL:
|
||||
return getattr(super(Scene, self), "leave_progress_bars", False)
|
||||
else:
|
||||
return config["progress_bar"] == "leave"
|
||||
|
||||
def play(self, *args, **kwargs):
|
||||
def play(self, *args, **kwargs) -> None:
|
||||
"""Overloads `self.play` and increment animation count."""
|
||||
super().play(*args, **kwargs)
|
||||
self.current_animation += 1
|
||||
|
||||
def pause(self):
|
||||
def pause(self) -> None:
|
||||
"""Creates a new slide with previous animations."""
|
||||
self.slides.append(
|
||||
SlideConfig(
|
||||
@ -94,12 +94,12 @@ class Slide(Scene):
|
||||
self.current_slide += 1
|
||||
self.pause_start_animation = self.current_animation
|
||||
|
||||
def start_loop(self):
|
||||
def start_loop(self) -> None:
|
||||
"""Starts a loop."""
|
||||
assert self.loop_start_animation is None, "You cannot nest loops"
|
||||
self.loop_start_animation = self.current_animation
|
||||
|
||||
def end_loop(self):
|
||||
def end_loop(self) -> None:
|
||||
"""Ends an existing loop."""
|
||||
assert (
|
||||
self.loop_start_animation is not None
|
||||
@ -116,7 +116,7 @@ class Slide(Scene):
|
||||
self.loop_start_animation = None
|
||||
self.pause_start_animation = self.current_animation
|
||||
|
||||
def save_slides(self, use_cache=True):
|
||||
def save_slides(self, use_cache=True) -> None:
|
||||
"""
|
||||
Saves slides, optionally using cached files.
|
||||
|
||||
@ -182,12 +182,12 @@ class Slide(Scene):
|
||||
f"Slide '{scene_name}' configuration written in '{os.path.abspath(slide_path)}'"
|
||||
)
|
||||
|
||||
def run(self, *args, **kwargs):
|
||||
def run(self, *args, **kwargs) -> None:
|
||||
"""MANIMGL renderer"""
|
||||
super().run(*args, **kwargs)
|
||||
self.save_slides(use_cache=False)
|
||||
|
||||
def render(self, *args, **kwargs):
|
||||
def render(self, *args, **kwargs) -> None:
|
||||
"""MANIM render"""
|
||||
# We need to disable the caching limit since we rely on intermidiate files
|
||||
max_files_cached = config["max_files_cached"]
|
||||
|
Reference in New Issue
Block a user