-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathco_cellmagic.py
118 lines (107 loc) · 4.17 KB
/
co_cellmagic.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
from io import BytesIO
from base64 import b64decode
from IPython.core import magic_arguments
from IPython.core.magic import Magics, cell_magic, magics_class
from IPython.display import display
from IPython.utils.capture import capture_output
from PIL import Image
from pathlib import Path
from pprint import pprint # for debugging
@magics_class
class CaptureMagic(Magics):
@magic_arguments.magic_arguments() ################### IMAGE
@magic_arguments.argument(
"--path",
"-p",
default=None,
help=(
"The path where the image will be saved to. When there is more then one image, multiple paths have to be defined"
),
)
@magic_arguments.argument(
"--compression",
"-c",
default=None,
help=(
"Defines the amount of compression, quality can be from 0.1 - 100 , images must be .jpg"
),
)
@cell_magic
def capture_img(self, line, cell):
args = magic_arguments.parse_argstring(CaptureMagic.capture_img, line)
paths = args.path.strip('"').split(" ")
with capture_output(stdout=False, stderr=False, display=True) as result:
self.shell.run_cell(cell)
for output in result.outputs:
display(output)
data = output.data
if "image/png" in data:
path = paths.pop(0)
if not path:
raise ValueError("Too few paths given!")
png_bytes = data["image/png"]
if isinstance(png_bytes, str):
png_bytes = b64decode(png_bytes)
assert isinstance(png_bytes, bytes)
bytes_io = BytesIO(png_bytes)
img = Image.open(bytes_io)
if args.compression:
if img.mode != "RGB":
img = img.convert("RGB")
img.save(path, "JPEG", optimize=True, quality=int(args.compression))
else:
img.save(path, "png")
@magic_arguments.magic_arguments() ################### TEXT
@magic_arguments.argument(
"--path",
"-p",
default=None,
help=(
"The path where the text will be saved to"
),
)
@cell_magic
def capture_text(self, line, cell):
args = magic_arguments.parse_argstring(CaptureMagic.capture_text, line)
path = args.path.strip('"')
with capture_output(stdout=True, stderr=False, display=False) as result:
self.shell.run_cell(cell)
message = result.stdout
if len(message) == 0:
raise ValueError("No standard output (stdout) found!")
print(message)
dest = Path(path)
dest.write_text(message)
@magic_arguments.magic_arguments() ################### Video
@magic_arguments.argument(
"--path",
"-p",
default=None,
help=(
"The path where the video will be saved to. When there is more then one video, multiple paths have to be defined"
),
)
@cell_magic
def capture_video(self, line, cell):
args = magic_arguments.parse_argstring(CaptureMagic.capture_video, line)
paths = args.path.strip('"').split(" ")
with capture_output(stdout=False, stderr=False, display=True) as result:
self.shell.run_cell(cell)
for output in result.outputs:
display(output) # only disabled for debugging
global data # for debugging
data = output.data
pprint(data) # for debugging
print("#####")
if "text/html" in data: # this is not nice, is there any better way to access IPython.core.display.Video object ?
path = paths.pop(0)
if not path:
raise ValueError("Too few paths given!")
video_object = data["text/html"]
split_string = video_object.split('"')
video_url = split_string[1]
print(video_url) # for debugging
print(path) # for debugging
dest = Path(path)
src = Path(video_url)
dest.write_bytes(src.read_bytes())