iruby 0.2.9 → 0.6.1

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.
Files changed (72) hide show
  1. checksums.yaml +5 -5
  2. data/.github/workflows/ubuntu.yml +62 -0
  3. data/CHANGES +64 -0
  4. data/Gemfile +3 -1
  5. data/LICENSE +1 -1
  6. data/README.md +120 -92
  7. data/Rakefile +36 -10
  8. data/ci/Dockerfile.base.erb +41 -0
  9. data/ci/Dockerfile.main.erb +7 -0
  10. data/ci/requirements.txt +1 -0
  11. data/docker/setup.sh +15 -0
  12. data/docker/test.sh +7 -0
  13. data/iruby.gemspec +13 -18
  14. data/lib/iruby.rb +13 -6
  15. data/lib/iruby/backend.rb +38 -9
  16. data/lib/iruby/command.rb +68 -12
  17. data/lib/iruby/display.rb +81 -41
  18. data/lib/iruby/event_manager.rb +40 -0
  19. data/lib/iruby/formatter.rb +3 -3
  20. data/lib/iruby/input.rb +6 -6
  21. data/lib/iruby/input/README.ipynb +55 -3
  22. data/lib/iruby/input/README.md +299 -0
  23. data/lib/iruby/input/autoload.rb +3 -2
  24. data/lib/iruby/input/builder.rb +4 -4
  25. data/lib/iruby/input/button.rb +2 -2
  26. data/lib/iruby/input/cancel.rb +1 -1
  27. data/lib/iruby/input/checkbox.rb +22 -4
  28. data/lib/iruby/input/date.rb +17 -6
  29. data/lib/iruby/input/field.rb +5 -4
  30. data/lib/iruby/input/file.rb +3 -3
  31. data/lib/iruby/input/form.rb +6 -6
  32. data/lib/iruby/input/label.rb +9 -3
  33. data/lib/iruby/input/multiple.rb +76 -0
  34. data/lib/iruby/input/popup.rb +5 -2
  35. data/lib/iruby/input/radio.rb +18 -6
  36. data/lib/iruby/input/select.rb +26 -12
  37. data/lib/iruby/input/textarea.rb +2 -1
  38. data/lib/iruby/input/widget.rb +2 -2
  39. data/lib/iruby/jupyter.rb +77 -0
  40. data/lib/iruby/kernel.rb +171 -31
  41. data/lib/iruby/ostream.rb +29 -8
  42. data/lib/iruby/session.rb +116 -0
  43. data/lib/iruby/session/{rbczmq.rb → cztop.rb} +21 -19
  44. data/lib/iruby/session/ffi_rzmq.rb +1 -1
  45. data/lib/iruby/session_adapter.rb +72 -0
  46. data/lib/iruby/session_adapter/cztop_adapter.rb +45 -0
  47. data/lib/iruby/session_adapter/ffirzmq_adapter.rb +55 -0
  48. data/lib/iruby/session_adapter/pyzmq_adapter.rb +77 -0
  49. data/lib/iruby/session_adapter/test_adapter.rb +49 -0
  50. data/lib/iruby/utils.rb +13 -2
  51. data/lib/iruby/version.rb +1 -1
  52. data/run-test.sh +12 -0
  53. data/tasks/ci.rake +65 -0
  54. data/test/helper.rb +133 -0
  55. data/test/integration_test.rb +22 -11
  56. data/test/iruby/backend_test.rb +37 -0
  57. data/test/iruby/command_test.rb +207 -0
  58. data/test/iruby/event_manager_test.rb +92 -0
  59. data/test/iruby/jupyter_test.rb +27 -0
  60. data/test/iruby/kernel_test.rb +153 -0
  61. data/test/iruby/mime_test.rb +43 -0
  62. data/test/iruby/multi_logger_test.rb +1 -2
  63. data/test/iruby/session_adapter/cztop_adapter_test.rb +20 -0
  64. data/test/iruby/session_adapter/ffirzmq_adapter_test.rb +20 -0
  65. data/test/iruby/session_adapter/session_adapter_test_base.rb +27 -0
  66. data/test/iruby/session_adapter_test.rb +91 -0
  67. data/test/iruby/session_test.rb +48 -0
  68. data/test/run-test.rb +19 -0
  69. metadata +107 -50
  70. data/.travis.yml +0 -16
  71. data/CONTRIBUTORS +0 -19
  72. data/test/test_helper.rb +0 -5
@@ -2,7 +2,7 @@ begin
2
2
  require 'erector'
3
3
  rescue LoadError
4
4
  raise LoadError, <<-ERROR.gsub(/\s+/,' ')
5
- IRuby::Input requires the erector gem.
5
+ IRuby::Input requires the erector gem.
6
6
  `gem install erector` or add `gem 'erector'`
7
7
  it to your Gemfile to continue.
8
8
  ERROR
@@ -21,4 +21,5 @@ require 'iruby/input/select'
21
21
  require 'iruby/input/checkbox'
22
22
  require 'iruby/input/radio'
23
23
  require 'iruby/input/textarea'
24
- require 'iruby/input/date'
24
+ require 'iruby/input/date'
25
+ require 'iruby/input/multiple'
@@ -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
@@ -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
  )
@@ -22,7 +22,7 @@ module IRuby
22
22
  def widget_html
23
23
  button(
24
24
  @label,
25
- type: 'button',
25
+ type: 'button',
26
26
  :'data-dismiss' => 'modal',
27
27
  class: "btn btn-danger pull-right iruby-cancel"
28
28
  )
@@ -1,7 +1,7 @@
1
1
  module IRuby
2
2
  module Input
3
3
  class Checkbox < Label
4
- needs :options
4
+ needs :options, :default
5
5
 
6
6
  builder :checkbox do |*args, **params|
7
7
  key = :checkbox
@@ -9,11 +9,24 @@ module IRuby
9
9
 
10
10
  params[:key] = unique_key(key)
11
11
  params[:options] = args
12
+
13
+ params[:default] = case params[:default]
14
+ when false, nil
15
+ []
16
+ when true
17
+ [*params[:options]]
18
+ else
19
+ [*params[:default]]
20
+ end
21
+
12
22
  add_field Checkbox.new(**params)
13
23
  end
14
24
 
15
25
  def widget_css
16
- '.iruby-checkbox-container { margin-left: 10px; }'
26
+ <<-CSS
27
+ .iruby-checkbox.form-control { display: inline-table; }
28
+ .iruby-checkbox .checkbox-inline { margin: 0 15px 0 0; }
29
+ CSS
17
30
  end
18
31
 
19
32
  def widget_js
@@ -30,6 +43,8 @@ module IRuby
30
43
  $(parent).data('iruby-value', null);
31
44
  }
32
45
  });
46
+
47
+ $('.iruby-checkbox input').trigger('change');
33
48
  JS
34
49
  end
35
50
 
@@ -41,9 +56,12 @@ module IRuby
41
56
  widget_label do
42
57
  div **params do
43
58
  @options.each do |option|
44
- label class: 'checkbox-inline' do
59
+ label class: 'checkbox-inline' do
45
60
  input(
46
- name: @key, value: option, type: 'checkbox'
61
+ name: @key,
62
+ value: option,
63
+ type: 'checkbox',
64
+ checked: @default.include?(option)
47
65
  )
48
66
  text option
49
67
  end
@@ -1,26 +1,37 @@
1
1
  module IRuby
2
2
  module Input
3
3
  class Date < Field
4
- needs js_class: 'iruby-date'
4
+ needs js_class: 'iruby-date', icon: '📅'
5
5
 
6
6
  builder :date do |key='date', **params|
7
+ params[:default] ||= false
7
8
  params[:key] = unique_key key
9
+
10
+ if params[:default].is_a? Time
11
+ params[:default] = params[:default].strftime('%m/%d/%Y')
12
+ end
13
+
8
14
  add_field Date.new(**params)
15
+
16
+ process params[:key] do |result,key,value|
17
+ result[key.to_sym] = Time.strptime(value,'%m/%d/%Y')
18
+ end
9
19
  end
10
20
 
11
21
  def widget_css
12
- '#ui-datepicker-div { z-index: 2000; }'
22
+ '#ui-datepicker-div { z-index: 2000 !important; }'
13
23
  end
14
24
 
15
- def widget_js
25
+ def widget_js
16
26
  <<-JS
17
27
  $('.iruby-date').datepicker({
28
+ dateFormat: 'mm/dd/yy',
18
29
  onClose: function(date) {
19
- $('.iruby-date').data('iruby-value', date);
20
- }
30
+ $(this).data('iruby-value', date);
31
+ }
21
32
  });
22
33
  JS
23
34
  end
24
35
  end
25
36
  end
26
- end
37
+ end
@@ -1,7 +1,7 @@
1
1
  module IRuby
2
2
  module Input
3
3
  class Field < Label
4
- needs :type => 'text', js_class: 'iruby-field'
4
+ needs default: nil, type: 'text', js_class: 'iruby-field'
5
5
 
6
6
  builder :input do |key='input', **params|
7
7
  params[:key] = unique_key key
@@ -17,11 +17,12 @@ module IRuby
17
17
  end
18
18
 
19
19
  def widget_html
20
- widget_label do
20
+ widget_label do
21
21
  input(
22
- type: @type,
22
+ type: @type,
23
23
  :'data-iruby-key' => @key,
24
- class: "form-control #{@js_class}"
24
+ class: "form-control #{@js_class}",
25
+ value: @default
25
26
  )
26
27
  end
27
28
  end
@@ -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
  )
@@ -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
@@ -1,13 +1,19 @@
1
1
  module IRuby
2
2
  module Input
3
3
  class Label < Widget
4
- needs label: nil
4
+ needs label: nil, icon: nil
5
5
 
6
6
  def widget_label
7
- label = @label || to_label(@key)
8
7
  div class: 'iruby-label input-group' do
9
- span label, class: 'input-group-addon'
8
+ span class: 'input-group-addon' do
9
+ text @label || to_label(@key)
10
+ end
11
+
10
12
  yield
13
+
14
+ if @icon
15
+ span @icon, class: "input-group-addon"
16
+ end
11
17
  end
12
18
  end
13
19
 
@@ -0,0 +1,76 @@
1
+ module IRuby
2
+ module Input
3
+ class Multiple < Label
4
+ needs :options, :default, size: nil
5
+
6
+ builder :multiple do |*args, **params|
7
+ key = :multiple
8
+ key, *args = args if args.first.is_a? Symbol
9
+
10
+ params[:key] = unique_key(key)
11
+ params[:options] = args
12
+
13
+ params[:default] = case params[:default]
14
+ when false, nil
15
+ []
16
+ when true
17
+ [*params[:options]]
18
+ else
19
+ [*params[:default]]
20
+ end
21
+
22
+ add_field Multiple.new(**params)
23
+ end
24
+
25
+ def widget_css
26
+ <<-CSS
27
+ .iruby-multiple {
28
+ display: table;
29
+ min-width: 25%;
30
+ }
31
+ .form-control.iruby-multiple-container {
32
+ display: table;
33
+ }
34
+ CSS
35
+ end
36
+
37
+ def widget_js
38
+ <<-JS
39
+ $('.iruby-multiple').change(function(){
40
+ var multiple = $(this);
41
+ multiple.data('iruby-value', []);
42
+
43
+ multiple.find(':selected').each(function(){
44
+ multiple.data('iruby-value').push($(this).val());
45
+ });
46
+
47
+ if (multiple.data('iruby-value').length == 0) {
48
+ multiple.data('iruby-value', null);
49
+ }
50
+ });
51
+
52
+ $('.iruby-multiple').trigger('change');
53
+ JS
54
+ end
55
+
56
+ def widget_html
57
+ widget_label do
58
+ div class: 'form-control iruby-multiple-container' do
59
+ params = {
60
+ size: @size,
61
+ multiple: true,
62
+ class: 'iruby-multiple',
63
+ :'data-iruby-key' => @key
64
+ }
65
+
66
+ select **params do
67
+ @options.each do |o|
68
+ option o, selected: @default.include?(o)
69
+ end
70
+ end
71
+ end
72
+ end
73
+ end
74
+ end
75
+ end
76
+ end
@@ -21,9 +21,12 @@ module IRuby
21
21
  #{widget_join :widget_js, @form, *@buttons}
22
22
 
23
23
  var popup = $(this);
24
+
24
25
  $('#iruby-form').submit(function() {
25
26
  popup.modal('hide');
26
- })
27
+ });
28
+
29
+ Jupyter.notebook.keyboard_manager.disable();
27
30
  }
28
31
  });
29
32
 
@@ -35,4 +38,4 @@ module IRuby
35
38
  end
36
39
  end
37
40
  end
38
- end
41
+ end
@@ -1,25 +1,34 @@
1
1
  module IRuby
2
2
  module Input
3
3
  class Radio < Label
4
- needs :options
4
+ needs :options, :default
5
5
 
6
6
  builder :radio do |*args, **params|
7
7
  key = :radio
8
8
  key, *args = args if args.first.is_a? Symbol
9
-
9
+
10
10
  params[:key] = unique_key(key)
11
11
  params[:options] = args
12
+ params[:default] ||= false
12
13
  add_field Radio.new(**params)
13
14
  end
14
15
 
16
+ def widget_css
17
+ <<-CSS
18
+ .iruby-radio.form-control { display: inline-table; }
19
+ .iruby-radio .radio-inline { margin: 0 15px 0 0; }
20
+ CSS
21
+ end
22
+
15
23
  def widget_js
16
24
  <<-JS
17
25
  $('.iruby-radio input').change(function(){
18
26
  var parent = $(this).closest('.iruby-radio');
19
- $(parent).data('iruby-value',
27
+ $(parent).data('iruby-value',
20
28
  $(parent).find(':checked').val()
21
29
  );
22
30
  });
31
+ $('.iruby-radio input').trigger('change');
23
32
  JS
24
33
  end
25
34
 
@@ -29,12 +38,15 @@ module IRuby
29
38
  :'data-iruby-value' => @options.first,
30
39
  class: 'iruby-radio form-control'
31
40
  }
32
- widget_label do
41
+ widget_label do
33
42
  div **params do
34
43
  @options.each do |option|
35
- label class: 'radio-inline' do
44
+ label class: 'radio-inline' do
36
45
  input(
37
- name: @key, value: option, type: 'radio'
46
+ name: @key,
47
+ value: option,
48
+ type: 'radio',
49
+ checked: @default == option
38
50
  )
39
51
  text option
40
52
  end