Skip to content

Commit 91c4f3e

Browse files
author
Oliver Strait
committed
Add functionality of cached version number
1 parent 9e62b2d commit 91c4f3e

File tree

1 file changed

+54
-42
lines changed

1 file changed

+54
-42
lines changed

manim/cli/render/commands.py

Lines changed: 54 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -8,11 +8,10 @@
88

99
from __future__ import annotations
1010

11-
import http.client
1211
import json
12+
import os
1313
import sys
14-
import urllib.error
15-
import urllib.request
14+
import time
1615
from argparse import Namespace
1716
from pathlib import Path
1817
from typing import TYPE_CHECKING, Any, cast
@@ -100,8 +99,8 @@ def render(**kwargs: Any) -> ClickArgs | dict[str, Any]:
10099
return click_args
101100

102101
config.digest_args(click_args)
103-
file = Path(config.input_file)
104-
scenes = solve_rendrered_scenes(file)
102+
103+
scenes = solve_rendrered_scenes(config.input_file)
105104

106105
if config.renderer == RendererType.OPENGL:
107106
from manim.renderer.opengl_renderer import OpenGLRenderer
@@ -143,41 +142,53 @@ def render(**kwargs: Any) -> ClickArgs | dict[str, Any]:
143142

144143

145144
def version_notification() -> None:
146-
### NOTE TODO This has fundamental problem of connecting every time into internet
147-
### As many times Renders are executed during a day.
148-
### There should be a caching mechanisim that will safe simple timecode and result in
149-
### Cached file to be fetched in most of times.
145+
"""Fetch version from Internet or use cache"""
146+
file = Path(os.path.dirname(__file__)) / ".version_cache.log"
147+
stable = None
148+
149+
if file.exists():
150+
with file.open() as f:
151+
last_time = f.readline()
152+
if not time.time() - int(last_time) > 86_400:
153+
stable = f.readline()
154+
155+
if stable is None:
156+
new_stable = fetch_version()
157+
if new_stable:
158+
with file.open(mode="w") as f:
159+
f.write(str(int(time.time())) + "\n" + str(new_stable))
160+
stable = new_stable
161+
162+
if stable != __version__:
163+
console.print(
164+
f"You are using manim version [red]v{__version__}[/red], but version [green]v{stable}[/green] is available.",
165+
)
166+
console.print(
167+
"You should consider upgrading via [yellow]pip install -U manim[/yellow]",
168+
)
169+
170+
171+
def fetch_version() -> str | None:
172+
import http.client
173+
import urllib.error
174+
import urllib.request
150175

151176
manim_info_url = "https://pypi.org/pypi/manim/json"
152177
warn_prompt = "Cannot check if latest release of manim is installed"
153-
178+
request = urllib.request.Request(manim_info_url)
154179
try:
155-
with urllib.request.urlopen(
156-
urllib.request.Request(manim_info_url),
157-
timeout=10,
158-
) as response:
180+
with urllib.request.urlopen(request, timeout=10) as response:
159181
response = cast(http.client.HTTPResponse, response)
160182
json_data = json.loads(response.read())
161-
except urllib.error.HTTPError:
162-
logger.debug("HTTP Error: %s", warn_prompt)
163-
except urllib.error.URLError:
164-
logger.debug("URL Error: %s", warn_prompt)
183+
184+
except (Exception, urllib.error.HTTPError, urllib.error.URLError) as e:
185+
logger.debug(f"{e}: {warn_prompt} ")
186+
return None
165187
except json.JSONDecodeError:
166-
logger.debug(
167-
"Error while decoding JSON from %r: %s", manim_info_url, warn_prompt
168-
)
169-
except Exception:
170-
logger.debug("Something went wrong: %s", warn_prompt)
188+
logger.debug(f"Error while decoding JSON from [{manim_info_url}]: warn_prompt")
189+
return None
171190
else:
172-
stable = json_data["info"]["version"]
173-
174-
if stable != __version__:
175-
console.print(
176-
f"You are using manim version [red]v{__version__}[/red], but version [green]v{stable}[/green] is available.",
177-
)
178-
console.print(
179-
"You should consider upgrading via [yellow]pip install -U manim[/yellow]",
180-
)
191+
return str(json_data["info"]["version"])
181192

182193

183194
def warn_and_change_deprecated_args(kwargs: dict[str, Any]) -> None:
@@ -198,7 +209,14 @@ def warn_and_change_deprecated_args(kwargs: dict[str, Any]) -> None:
198209
)
199210

200211

201-
def get_scenes_to_render(scene_classes: list[type[Scene]]) -> list[type[Scene]]:
212+
def select_scenes(scene_classes: list[type[Scene]]) -> list[type[Scene]]:
213+
"""Collection of selection checks for inserted scenes"""
214+
if not scene_classes:
215+
logger.error(NO_SCENE_MESSAGE)
216+
return []
217+
elif config.write_all:
218+
return scene_classes
219+
202220
result = []
203221
for scene_name in config.scene_names:
204222
found = False
@@ -230,11 +248,11 @@ def get_scenes_to_render(scene_classes: list[type[Scene]]) -> list[type[Scene]]:
230248
return classes
231249

232250

233-
def solve_rendrered_scenes(file_path_input: Path | str) -> list[type[Scene]]:
251+
def solve_rendrered_scenes(file_path_input: str) -> list[type[Scene]]:
234252
"""Return scenes from file path or create CLI prompt for input"""
235253
from ...scene.scene import Scene
236254

237-
if str(file_path_input) == "-":
255+
if file_path_input == "-":
238256
try:
239257
code = code_input_prompt()
240258
module = module_from_text(code)
@@ -248,10 +266,4 @@ def solve_rendrered_scenes(file_path_input: Path | str) -> list[type[Scene]]:
248266

249267
scenes = search_classes_from_module(module, Scene)
250268

251-
if not scenes:
252-
logger.error(NO_SCENE_MESSAGE)
253-
return []
254-
elif config.write_all:
255-
return scenes
256-
else:
257-
return get_scenes_to_render(scenes)
269+
return select_scenes(scenes)

0 commit comments

Comments
 (0)