iruby 0.4.0 → 0.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.github/workflows/ubuntu.yml +62 -0
- data/CHANGES +24 -0
- data/Gemfile +0 -2
- data/LICENSE +1 -1
- data/README.md +66 -62
- data/Rakefile +10 -10
- data/ci/Dockerfile.main.erb +1 -3
- data/iruby.gemspec +13 -19
- data/lib/iruby.rb +2 -6
- data/lib/iruby/backend.rb +19 -5
- data/lib/iruby/display.rb +57 -41
- data/lib/iruby/formatter.rb +3 -3
- data/lib/iruby/input.rb +6 -6
- data/lib/iruby/input/autoload.rb +1 -1
- data/lib/iruby/input/builder.rb +4 -4
- data/lib/iruby/input/button.rb +2 -2
- data/lib/iruby/input/cancel.rb +1 -1
- data/lib/iruby/input/checkbox.rb +3 -3
- data/lib/iruby/input/date.rb +3 -3
- data/lib/iruby/input/field.rb +2 -2
- data/lib/iruby/input/file.rb +3 -3
- data/lib/iruby/input/form.rb +6 -6
- data/lib/iruby/input/label.rb +4 -4
- data/lib/iruby/input/multiple.rb +10 -10
- data/lib/iruby/input/popup.rb +2 -2
- data/lib/iruby/input/radio.rb +6 -6
- data/lib/iruby/input/select.rb +8 -8
- data/lib/iruby/input/textarea.rb +1 -1
- data/lib/iruby/input/widget.rb +2 -2
- data/lib/iruby/jupyter.rb +1 -0
- data/lib/iruby/kernel.rb +18 -13
- data/lib/iruby/ostream.rb +22 -10
- data/lib/iruby/session_adapter.rb +1 -3
- data/lib/iruby/session_adapter/pyzmq_adapter.rb +11 -10
- data/lib/iruby/utils.rb +4 -0
- data/lib/iruby/version.rb +1 -1
- data/run-test.sh +1 -1
- data/test/helper.rb +90 -0
- data/test/integration_test.rb +1 -2
- data/test/iruby/backend_test.rb +37 -0
- data/test/iruby/command_test.rb +0 -1
- data/test/iruby/jupyter_test.rb +0 -1
- data/test/iruby/mime_test.rb +32 -0
- data/test/iruby/multi_logger_test.rb +0 -1
- data/test/iruby/session_adapter/cztop_adapter_test.rb +1 -1
- data/test/iruby/session_adapter/ffirzmq_adapter_test.rb +1 -1
- data/test/iruby/session_adapter/session_adapter_test_base.rb +1 -3
- data/test/iruby/session_adapter_test.rb +42 -67
- data/test/iruby/session_test.rb +9 -15
- data/test/run-test.rb +18 -0
- metadata +68 -64
- data/.travis.yml +0 -41
- data/CONTRIBUTORS +0 -19
- data/lib/iruby/session/rbczmq.rb +0 -72
- data/lib/iruby/session_adapter/rbczmq_adapter.rb +0 -33
- data/test/iruby/session_adapter/rbczmq_adapter_test.rb +0 -37
- data/test/test_helper.rb +0 -48
data/lib/iruby/display.rb
CHANGED
@@ -11,7 +11,10 @@ module IRuby
|
|
11
11
|
obj = obj.object
|
12
12
|
|
13
13
|
fuzzy_mime = options[:format] # Treated like a fuzzy mime type
|
14
|
-
|
14
|
+
unless !fuzzy_mime || String === fuzzy_mime
|
15
|
+
raise 'Invalid argument :format'
|
16
|
+
end
|
17
|
+
|
15
18
|
if exact_mime = options[:mime]
|
16
19
|
raise 'Invalid argument :mime' unless String === exact_mime
|
17
20
|
raise 'Invalid mime type' unless exact_mime.include?('/')
|
@@ -27,32 +30,38 @@ module IRuby
|
|
27
30
|
|
28
31
|
# As a last resort, interpret string representation of the object
|
29
32
|
# as the given mime type.
|
30
|
-
|
33
|
+
if exact_mime && data.none? { |m, _| exact_mime == m }
|
34
|
+
data[exact_mime] = protect(exact_mime, obj)
|
35
|
+
end
|
31
36
|
|
32
37
|
data
|
33
38
|
end
|
34
39
|
|
35
|
-
def clear_output(wait=false)
|
36
|
-
IRuby::Kernel.instance.session.send(:publish, :clear_output,
|
40
|
+
def clear_output(wait = false)
|
41
|
+
IRuby::Kernel.instance.session.send(:publish, :clear_output, wait: wait)
|
37
42
|
end
|
38
43
|
|
39
44
|
private
|
40
45
|
|
41
46
|
def protect(mime, data)
|
42
|
-
|
47
|
+
MIME::Type.new(mime).ascii? ? data.to_s : [data.to_s].pack('m0')
|
43
48
|
end
|
44
49
|
|
45
50
|
def render(data, obj, exact_mime, fuzzy_mime)
|
46
51
|
# Filter matching renderer by object type
|
47
|
-
renderer = Registry.renderer.select {|r| r.match?(obj) }
|
52
|
+
renderer = Registry.renderer.select { |r| r.match?(obj) }
|
48
53
|
|
49
54
|
matching_renderer = nil
|
50
55
|
|
51
56
|
# Find exactly matching display by exact_mime
|
52
|
-
|
57
|
+
if exact_mime
|
58
|
+
matching_renderer = renderer.find { |r| exact_mime == r.mime }
|
59
|
+
end
|
53
60
|
|
54
61
|
# Find fuzzy matching display by fuzzy_mime
|
55
|
-
|
62
|
+
if fuzzy_mime
|
63
|
+
matching_renderer ||= renderer.find { |r| r.mime&.include?(fuzzy_mime) }
|
64
|
+
end
|
56
65
|
|
57
66
|
renderer.unshift matching_renderer if matching_renderer
|
58
67
|
|
@@ -73,7 +82,8 @@ module IRuby
|
|
73
82
|
attr_reader :object, :options
|
74
83
|
|
75
84
|
def initialize(object, options)
|
76
|
-
@object
|
85
|
+
@object = object
|
86
|
+
@options = options
|
77
87
|
end
|
78
88
|
|
79
89
|
class << self
|
@@ -91,10 +101,13 @@ module IRuby
|
|
91
101
|
end
|
92
102
|
|
93
103
|
class Renderer
|
94
|
-
attr_reader :match, :mime, :
|
104
|
+
attr_reader :match, :mime, :priority
|
95
105
|
|
96
106
|
def initialize(match, mime, render, priority)
|
97
|
-
@match
|
107
|
+
@match = match
|
108
|
+
@mime = mime
|
109
|
+
@render = render
|
110
|
+
@priority = priority
|
98
111
|
end
|
99
112
|
|
100
113
|
def match?(obj)
|
@@ -114,7 +127,7 @@ module IRuby
|
|
114
127
|
@renderer ||= []
|
115
128
|
end
|
116
129
|
|
117
|
-
SUPPORTED_MIMES = %w
|
130
|
+
SUPPORTED_MIMES = %w[
|
118
131
|
text/plain
|
119
132
|
text/html
|
120
133
|
text/latex
|
@@ -122,7 +135,8 @@ module IRuby
|
|
122
135
|
application/javascript
|
123
136
|
image/png
|
124
137
|
image/jpeg
|
125
|
-
image/svg+xml
|
138
|
+
image/svg+xml
|
139
|
+
]
|
126
140
|
|
127
141
|
def match(&block)
|
128
142
|
@match = block
|
@@ -131,7 +145,7 @@ module IRuby
|
|
131
145
|
end
|
132
146
|
|
133
147
|
def respond_to(name)
|
134
|
-
match {|obj| obj.respond_to?(name) }
|
148
|
+
match { |obj| obj.respond_to?(name) }
|
135
149
|
end
|
136
150
|
|
137
151
|
def type(&block)
|
@@ -153,7 +167,7 @@ module IRuby
|
|
153
167
|
|
154
168
|
def format(mime = nil, &block)
|
155
169
|
renderer << Renderer.new(@match, mime, block, @priority)
|
156
|
-
renderer.sort_by! {|r| -r.priority }
|
170
|
+
renderer.sort_by! { |r| -r.priority }
|
157
171
|
|
158
172
|
# Decrease priority implicitly for all formats
|
159
173
|
# which are added later for a type.
|
@@ -170,6 +184,7 @@ module IRuby
|
|
170
184
|
end
|
171
185
|
|
172
186
|
type { Numo::NArray }
|
187
|
+
format 'text/plain', &:inspect
|
173
188
|
format 'text/latex' do |obj|
|
174
189
|
obj.ndim == 2 ?
|
175
190
|
LaTeX.matrix(obj, obj.shape[0], obj.shape[1]) :
|
@@ -180,6 +195,7 @@ module IRuby
|
|
180
195
|
end
|
181
196
|
|
182
197
|
type { NArray }
|
198
|
+
format 'text/plain', &:inspect
|
183
199
|
format 'text/latex' do |obj|
|
184
200
|
obj.dim == 2 ?
|
185
201
|
LaTeX.matrix(obj.transpose(1, 0), obj.shape[1], obj.shape[0]) :
|
@@ -241,37 +257,41 @@ module IRuby
|
|
241
257
|
|
242
258
|
match do |obj|
|
243
259
|
defined?(Magick::Image) && Magick::Image === obj ||
|
244
|
-
|
260
|
+
defined?(MiniMagick::Image) && MiniMagick::Image === obj
|
245
261
|
end
|
246
262
|
format 'image' do |obj|
|
247
263
|
format = obj.format || 'PNG'
|
248
|
-
[format == 'PNG' ? 'image/png' : 'image/jpeg', obj.to_blob {|i| i.format = format }]
|
264
|
+
[format == 'PNG' ? 'image/png' : 'image/jpeg', obj.to_blob { |i| i.format = format }]
|
249
265
|
end
|
250
266
|
|
251
|
-
|
252
|
-
|
253
|
-
obj.to_blob
|
267
|
+
match do |obj|
|
268
|
+
defined?(Vips::Image) && Vips::Image === obj
|
254
269
|
end
|
270
|
+
format do |obj|
|
271
|
+
# handles Vips::Error, vips_image_get: field "vips-loader" not found
|
272
|
+
loader = obj.get('vips-loader') rescue nil
|
273
|
+
if loader == 'jpegload'
|
274
|
+
['image/jpeg', obj.write_to_buffer('.jpg')]
|
275
|
+
else
|
276
|
+
# falls back to png for other/unknown types
|
277
|
+
['image/png', obj.write_to_buffer('.png')]
|
278
|
+
end
|
279
|
+
end
|
280
|
+
|
281
|
+
type { Gruff::Base }
|
282
|
+
format 'image/png', &:to_blob
|
255
283
|
|
256
284
|
respond_to :to_html
|
257
|
-
format 'text/html'
|
258
|
-
obj.to_html
|
259
|
-
end
|
285
|
+
format 'text/html', &:to_html
|
260
286
|
|
261
287
|
respond_to :to_latex
|
262
|
-
format 'text/latex'
|
263
|
-
obj.to_latex
|
264
|
-
end
|
288
|
+
format 'text/latex', &:to_latex
|
265
289
|
|
266
290
|
respond_to :to_tex
|
267
|
-
format 'text/latex'
|
268
|
-
obj.to_tex
|
269
|
-
end
|
291
|
+
format 'text/latex', &:to_tex
|
270
292
|
|
271
293
|
respond_to :to_javascript
|
272
|
-
format 'text/javascript'
|
273
|
-
obj.to_javascript
|
274
|
-
end
|
294
|
+
format 'text/javascript', &:to_javascript
|
275
295
|
|
276
296
|
respond_to :to_svg
|
277
297
|
format 'image/svg+xml' do |obj|
|
@@ -280,21 +300,17 @@ module IRuby
|
|
280
300
|
end
|
281
301
|
|
282
302
|
respond_to :to_iruby
|
283
|
-
format
|
284
|
-
obj.to_iruby
|
285
|
-
end
|
303
|
+
format(&:to_iruby)
|
286
304
|
|
287
|
-
match {|obj| obj.respond_to?(:path) && File.readable?(obj.path) }
|
305
|
+
match { |obj| obj.respond_to?(:path) && obj.method(:path).arity == 0 && File.readable?(obj.path) }
|
288
306
|
format do |obj|
|
289
|
-
mime =
|
307
|
+
mime = MIME::Types.of(obj.path).first.to_s
|
290
308
|
[mime, File.read(obj.path)] if SUPPORTED_MIMES.include?(mime)
|
291
309
|
end
|
292
310
|
|
293
311
|
type { Object }
|
294
|
-
priority
|
295
|
-
format 'text/plain'
|
296
|
-
obj.inspect
|
297
|
-
end
|
312
|
+
priority(-1000)
|
313
|
+
format 'text/plain', &:inspect
|
298
314
|
end
|
299
315
|
end
|
300
316
|
end
|
data/lib/iruby/formatter.rb
CHANGED
@@ -78,16 +78,16 @@ module IRuby
|
|
78
78
|
|
79
79
|
if maxcols && keys.size > maxcols
|
80
80
|
keys1 = keys[0...maxcols / 2]
|
81
|
-
keys2 = keys[-maxcols / 2
|
81
|
+
keys2 = keys[-maxcols / 2 + 1..-1]
|
82
82
|
if header
|
83
83
|
header1 = header[0...maxcols / 2]
|
84
|
-
header2 = header[-maxcols / 2
|
84
|
+
header2 = header[-maxcols / 2 + 1..-1]
|
85
85
|
end
|
86
86
|
end
|
87
87
|
|
88
88
|
if maxrows && rows.size > maxrows
|
89
89
|
rows1 = rows[0...maxrows / 2]
|
90
|
-
rows2 = rows[-maxrows / 2
|
90
|
+
rows2 = rows[-maxrows / 2 + 1..-1]
|
91
91
|
end
|
92
92
|
|
93
93
|
table = '<table>'
|
data/lib/iruby/input.rb
CHANGED
@@ -15,21 +15,21 @@ module IRuby
|
|
15
15
|
end
|
16
16
|
|
17
17
|
def form &block
|
18
|
-
builder = Builder.new
|
18
|
+
builder = Builder.new(&block)
|
19
19
|
form = InputForm.new(
|
20
|
-
fields: builder.fields,
|
20
|
+
fields: builder.fields,
|
21
21
|
buttons: builder.buttons
|
22
22
|
)
|
23
23
|
form.widget_display
|
24
24
|
builder.process_result form.submit
|
25
25
|
end
|
26
|
-
|
26
|
+
|
27
27
|
def popup title='Input', &block
|
28
|
-
builder = Builder.new
|
28
|
+
builder = Builder.new(&block)
|
29
29
|
form = InputForm.new fields: builder.fields
|
30
30
|
popup = Popup.new(
|
31
|
-
title: title,
|
32
|
-
form: form,
|
31
|
+
title: title,
|
32
|
+
form: form,
|
33
33
|
buttons: builder.buttons
|
34
34
|
)
|
35
35
|
popup.widget_display
|
data/lib/iruby/input/autoload.rb
CHANGED
data/lib/iruby/input/builder.rb
CHANGED
@@ -21,7 +21,7 @@ module IRuby
|
|
21
21
|
def html &block
|
22
22
|
add_field Class.new(Widget) {
|
23
23
|
define_method(:widget_html) { instance_eval &block }
|
24
|
-
}.new
|
24
|
+
}.new
|
25
25
|
end
|
26
26
|
|
27
27
|
def text string
|
@@ -44,7 +44,7 @@ module IRuby
|
|
44
44
|
end
|
45
45
|
end
|
46
46
|
|
47
|
-
private
|
47
|
+
private
|
48
48
|
|
49
49
|
def process key, &block
|
50
50
|
@processors[key.to_s] = block
|
@@ -52,14 +52,14 @@ module IRuby
|
|
52
52
|
|
53
53
|
def unique_key key
|
54
54
|
@keys ||= []
|
55
|
-
|
55
|
+
|
56
56
|
if @keys.include? key
|
57
57
|
(2..Float::INFINITY).each do |i|
|
58
58
|
test = "#{key}#{i}"
|
59
59
|
break key = test unless @keys.include? test
|
60
60
|
end
|
61
61
|
end
|
62
|
-
|
62
|
+
|
63
63
|
@keys << key; key
|
64
64
|
end
|
65
65
|
end
|
data/lib/iruby/input/button.rb
CHANGED
@@ -10,7 +10,7 @@ module IRuby
|
|
10
10
|
green: 'success',
|
11
11
|
aqua: 'info',
|
12
12
|
orange: 'warning',
|
13
|
-
red: 'danger',
|
13
|
+
red: 'danger',
|
14
14
|
none: 'link'
|
15
15
|
}
|
16
16
|
|
@@ -37,7 +37,7 @@ module IRuby
|
|
37
37
|
def widget_html
|
38
38
|
button(
|
39
39
|
@label || to_label(@key),
|
40
|
-
type: 'button',
|
40
|
+
type: 'button',
|
41
41
|
:'data-iruby-key' => @key,
|
42
42
|
class: "btn btn-#{COLORS[@color]} pull-right #{@js_class}"
|
43
43
|
)
|
data/lib/iruby/input/cancel.rb
CHANGED
data/lib/iruby/input/checkbox.rb
CHANGED
@@ -56,10 +56,10 @@ module IRuby
|
|
56
56
|
widget_label do
|
57
57
|
div **params do
|
58
58
|
@options.each do |option|
|
59
|
-
label class: 'checkbox-inline' do
|
59
|
+
label class: 'checkbox-inline' do
|
60
60
|
input(
|
61
|
-
name: @key,
|
62
|
-
value: option,
|
61
|
+
name: @key,
|
62
|
+
value: option,
|
63
63
|
type: 'checkbox',
|
64
64
|
checked: @default.include?(option)
|
65
65
|
)
|
data/lib/iruby/input/date.rb
CHANGED
@@ -6,7 +6,7 @@ module IRuby
|
|
6
6
|
builder :date do |key='date', **params|
|
7
7
|
params[:default] ||= false
|
8
8
|
params[:key] = unique_key key
|
9
|
-
|
9
|
+
|
10
10
|
if params[:default].is_a? Time
|
11
11
|
params[:default] = params[:default].strftime('%m/%d/%Y')
|
12
12
|
end
|
@@ -22,13 +22,13 @@ module IRuby
|
|
22
22
|
'#ui-datepicker-div { z-index: 2000 !important; }'
|
23
23
|
end
|
24
24
|
|
25
|
-
def widget_js
|
25
|
+
def widget_js
|
26
26
|
<<-JS
|
27
27
|
$('.iruby-date').datepicker({
|
28
28
|
dateFormat: 'mm/dd/yy',
|
29
29
|
onClose: function(date) {
|
30
30
|
$(this).data('iruby-value', date);
|
31
|
-
}
|
31
|
+
}
|
32
32
|
});
|
33
33
|
JS
|
34
34
|
end
|
data/lib/iruby/input/field.rb
CHANGED
data/lib/iruby/input/file.rb
CHANGED
@@ -13,10 +13,10 @@ module IRuby
|
|
13
13
|
|
14
14
|
# get rid of Chrome's silly path
|
15
15
|
name = value['name'].sub('C:\\fakepath\\','')
|
16
|
-
|
16
|
+
|
17
17
|
result[key.to_sym] = {
|
18
18
|
name: name,
|
19
|
-
data: uri.data,
|
19
|
+
data: uri.data,
|
20
20
|
content_type: uri.content_type
|
21
21
|
}
|
22
22
|
end
|
@@ -46,7 +46,7 @@ module IRuby
|
|
46
46
|
def widget_html
|
47
47
|
widget_label do
|
48
48
|
input(
|
49
|
-
type: 'file',
|
49
|
+
type: 'file',
|
50
50
|
:'data-iruby-key' => @key,
|
51
51
|
class: 'form-control iruby-file'
|
52
52
|
)
|
data/lib/iruby/input/form.rb
CHANGED
@@ -5,7 +5,7 @@ module IRuby
|
|
5
5
|
class InputForm < Widget
|
6
6
|
needs :fields, buttons: []
|
7
7
|
|
8
|
-
def widget_js
|
8
|
+
def widget_js
|
9
9
|
javascript = <<-JS
|
10
10
|
var remove = function () {
|
11
11
|
Jupyter.notebook.kernel.send_input_reply(
|
@@ -14,7 +14,7 @@ module IRuby
|
|
14
14
|
})
|
15
15
|
);
|
16
16
|
};
|
17
|
-
|
17
|
+
|
18
18
|
$("#iruby-form").on("remove", remove);
|
19
19
|
|
20
20
|
$('#iruby-form').submit(function() {
|
@@ -33,16 +33,16 @@ module IRuby
|
|
33
33
|
Jupyter.notebook.kernel.send_input_reply(
|
34
34
|
JSON.stringify({'#{@id}': result})
|
35
35
|
);
|
36
|
-
|
36
|
+
|
37
37
|
$(this).remove();
|
38
38
|
return false;
|
39
39
|
});
|
40
40
|
|
41
41
|
$('#iruby-form').keydown(function(event) {
|
42
|
-
if (event.keyCode == 13 && !event.shiftKey) {
|
42
|
+
if (event.keyCode == 13 && !event.shiftKey) {
|
43
43
|
$('#iruby-form').submit();
|
44
|
-
} else if (event.keyCode == 27) {
|
45
|
-
$('#iruby-form').remove();
|
44
|
+
} else if (event.keyCode == 27) {
|
45
|
+
$('#iruby-form').remove();
|
46
46
|
}
|
47
47
|
});
|
48
48
|
JS
|