browser_app_base 0.0.8 → 0.1.2

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: bf40fc8ffcf491a1fba31012f2e8e3aba1089dc14a8de381f420b33a51d2ca3a
4
- data.tar.gz: 3279233418b767f81a01350e5eb27f102f84f7b2c791d784ca0d25f8c58508c7
3
+ metadata.gz: 32eb1959381928c1c8be5a8760701706f771df4207232dd7a9047940a6f359a8
4
+ data.tar.gz: 38edd65c1cd9cbf4efa10a714bf1a0675fc9043642379b4c5b731e211ce3e0ad
5
5
  SHA512:
6
- metadata.gz: d264ee2f1c8d9aed28ea36c523c400d445570fd219271eece7135655831bb02d75c1ad5e4b77eda4fbba7fdeb32ebc7986765c43cc9702e4b8a32ee1351bf199
7
- data.tar.gz: 063d377c14dca4341cf963788c3de83a6bc7a6e6ddb93c5abc0bba06f40aa1cbb01596e19b95640ca7a99c11d5b996e1226c73326d9a95305351510dfb5e1a50
6
+ metadata.gz: e4aca516b044caa09f15225fb1dc0f3b61c256bb1b36351a1575fc0e6bc4e242e0d9c4f682fbb276250a4d6848e6c30d78490e73b2f78e9df4f82c056d266d37
7
+ data.tar.gz: 7b5ff83d5c26485836a54d41fbb8e71188147fc65663f4a3bfbd87407d45cf0dd701104c7826cff6116bd0f8f31574c45b412b69555dadcbecc5da3ad19a7977
data/.vscode/launch.json CHANGED
@@ -5,10 +5,16 @@
5
5
  "version": "0.2.0",
6
6
  "configurations": [
7
7
  {
8
- "name": "Debug Local File",
8
+ "name": "Debug create_browser_app.rb",
9
9
  "type": "Ruby",
10
10
  "request": "launch",
11
- "cwd": "${workspaceRoot}/lib/template/",
11
+ "program": "${workspaceRoot}/bin/create_browser_app.rb"
12
+ },
13
+ {
14
+ "name": "Debug start.rb",
15
+ "type": "Ruby",
16
+ "request": "launch",
17
+ "cwd": "${workspaceRoot}/lib/template",
12
18
  "program": "${workspaceRoot}/lib/template/start.rb"
13
19
  }
14
20
  ]
data/README.md CHANGED
@@ -58,12 +58,13 @@ ui application sample
58
58
 
59
59
  ## Start application
60
60
 
61
- $ cd ~/test/
62
- $ ruby start.rb
61
+ ```shell
62
+ $ /tmp/test/bin/start_my_app.rb
63
+ ```
63
64
 
64
65
  ## browser setting
65
66
 
66
- config/browser.json
67
+ ${home}/${app_nane}/config/browser.json
67
68
  Set the path for your Windows or Linux Chrome browser
68
69
 
69
70
  ```json
@@ -73,6 +74,34 @@ ui application sample
73
74
  }
74
75
  ```
75
76
 
77
+ ## Send a message from your browser application to your ruby application
78
+
79
+ Use the send_message function
80
+
81
+ main.js sample
82
+ ```javascript
83
+ $("#exec").click(function () {
84
+ send_message("exec:" + $("#upFile").val());
85
+ });
86
+
87
+ ```
88
+
89
+ ## Send a message from the ruby application to the browser application
90
+
91
+ Use the app_send function
92
+
93
+ my_app_sample.rb sample
94
+ ```ruby
95
+ class MyApp < AppMainBase
96
+ def start(argv)
97
+ # popup message
98
+ app_send("popup:message string")
99
+
100
+ # log message
101
+ yield "log message"
102
+ end
103
+ end
104
+ ```
76
105
 
77
106
  ## Development
78
107
 
@@ -0,0 +1,39 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require "fileutils"
4
+ require "facter"
5
+ require "tmpdir"
6
+
7
+ # tmpdirディレクトリにコピー
8
+ dir = File.dirname(File.expand_path(__FILE__ + "/../"))
9
+ home_dir = ENV["HOME"] + "/" + dir.split("/")[-1]
10
+ puts "home_dir=#{$home_dir}"
11
+ Dir.mktmpdir { |tmpdir|
12
+ outdir = tmpdir + "/" + dir.split("/")[-1]
13
+ FileUtils.mkdir_p outdir
14
+ FileUtils.mkdir_p home_dir
15
+ puts outdir
16
+ Dir.glob("#{dir}/lib/*") do |f|
17
+ if f =~ /config$/
18
+ # configはhomeにコピー
19
+ if !File.exists? "#{home_dir}/config"
20
+ puts "#{f} => #{home_dir}/"
21
+ FileUtils.cp_r f, "#{home_dir}/"
22
+ end
23
+ else
24
+ puts "#{f} => #{outdir}/"
25
+ FileUtils.cp_r f, "#{outdir}/"
26
+ end
27
+ end
28
+
29
+ FileUtils.cd "#{outdir}"
30
+ kernel = Facter.value(:kernel)
31
+ if kernel == "windows"
32
+ system "rubyw ./start.rb"
33
+ elsif kernel == "Linux"
34
+ system "ruby ./start.rb"
35
+ else
36
+ system "ruby ./start.rb"
37
+ end
38
+ FileUtils.cd ENV["HOME"]
39
+ }
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module BrowserAppBase
4
- VERSION = "0.0.8"
4
+ VERSION = "0.1.2"
5
5
  end
@@ -37,28 +37,33 @@ module BrowserAppBase
37
37
  puts "create application base #{dir}"
38
38
 
39
39
  FileUtils.mkdir_p dir
40
+ FileUtils.mkdir_p dir + "/lib/"
41
+ FileUtils.mkdir_p dir + "/bin/"
40
42
 
41
- path = File.dirname(File.expand_path(__FILE__))
42
- Dir.glob("#{path}/template/*") do |f|
43
- puts "#{f} => #{dir}"
44
- FileUtils.cp_r f, "#{dir}/"
43
+ path = File.dirname(File.expand_path(__FILE__)) + "/../"
44
+ Dir.glob("#{path}/lib/template/*") do |f|
45
+ puts "#{f} => #{dir}/lib"
46
+ FileUtils.cp_r f, "#{dir}/lib"
45
47
  end
46
48
 
47
49
  if app
48
50
  app_file = get_app_file(app)
49
51
 
52
+ puts "#{path}/bin/start_sample.rb #{dir}/bin/start_#{app_file}"
53
+ FileUtils.cp_r "#{path}/bin/start_sample.rb", "#{dir}/bin/start_#{app_file}"
54
+
50
55
  load_app = <<"EOS"
51
56
  require '#{app_file}'
52
57
  $app = #{get_app_name(app)}.new
53
58
  EOS
54
59
 
55
- File.open("#{dir}/app_load.rb", "w") do |f|
60
+ File.open("#{dir}/lib/app_load.rb", "w") do |f|
56
61
  f.write load_app
57
62
  end
58
63
 
59
64
  puts "create #{app_file}"
60
- new_file = "#{dir}/#{app_file}"
61
- FileUtils.cp("#{dir}/my_app_sample.rb", new_file)
65
+ new_file = "#{dir}/lib/#{app_file}"
66
+ FileUtils.cp("#{dir}/lib/my_app_sample.rb", new_file)
62
67
  buf = File.binread(new_file)
63
68
  File.binwrite(new_file, buf.gsub(/MyApp/, get_app_name(app)))
64
69
  end
@@ -1,4 +1,4 @@
1
1
  {
2
2
  "chrome_win": "start chrome",
3
- "chrome_linux": "/bin/google-chrome"
4
- }
3
+ "chrome_linux": "google-chrome"
4
+ }
@@ -1,7 +1,7 @@
1
1
  [
2
2
  {
3
3
  "name": "name1",
4
- "value": "value1",
4
+ "value": "value1 2 3 4",
5
5
  "type": "input",
6
6
  "select": "",
7
7
  "description": "設定項目1"
@@ -15,7 +15,7 @@
15
15
  },
16
16
  {
17
17
  "name": "name3",
18
- "value": "1",
18
+ "value": "2",
19
19
  "type": "select",
20
20
  "select": [
21
21
  "1",
@@ -8,8 +8,17 @@ require "json"
8
8
  require "./server"
9
9
  require "./wsserver"
10
10
 
11
+ access_log = File.new("#{$home_dir}/logs/sinatra.log", "a+")
12
+ access_log.sync = true
13
+ use Rack::CommonLogger, access_log
14
+
11
15
  get "/" do
12
- File.read("index.html")
16
+ File.read("html/index.html")
17
+ end
18
+
19
+ get "*.html" do |file|
20
+ content_type "text/html", :charset => "utf-8"
21
+ File.read "./html/#{file}.html"
13
22
  end
14
23
 
15
24
  get "/css/:name.css" do
@@ -27,7 +36,26 @@ end
27
36
  get "/config/*.*" do |file, ext|
28
37
  content_type "text/json", :charset => "utf-8"
29
38
  puts "#{file}.#{ext}"
30
- File.read "config/#{file}.#{ext}"
39
+ File.read "#{$home_dir}/config/#{file}.#{ext}"
40
+ end
41
+
42
+ post "/history/*.*" do |file, ext|
43
+ content_type "text/json", :charset => "utf-8"
44
+ puts "#{file}.#{ext}"
45
+ p = params[:param1]
46
+ begin
47
+ buf = File.read "#{$home_dir}/history/#{file}.#{ext}"
48
+ rescue
49
+ buf = ""
50
+ end
51
+ data = eval(buf)
52
+ if data != nil
53
+ if p != ""
54
+ JSON.generate data.find_all { |d| d =~ Regexp.new(p) }
55
+ else
56
+ JSON.generate data
57
+ end
58
+ end
31
59
  end
32
60
 
33
61
  get "/open_dialog" do
@@ -65,7 +93,7 @@ end
65
93
 
66
94
  configure do
67
95
  set :DoNotReverseLookup, true
68
- set :logging, false
96
+ set :logging, true
69
97
  set :default_encoding, "utf-8"
70
98
  set :server, :thin
71
99
 
@@ -74,6 +102,6 @@ configure do
74
102
 
75
103
  end
76
104
 
77
- #\ --port 53492
105
+ #\ --port 58656
78
106
 
79
107
  run Sinatra::Application
@@ -1,6 +1,6 @@
1
1
  body {
2
2
  color: #000000;
3
- background-color: #cac3ec4f;
3
+ background-color: #cac3ec4f;
4
4
  overflow: hidden;
5
5
  font-size: 12px;
6
6
  }
@@ -8,9 +8,12 @@ body {
8
8
  hr {
9
9
  color: #ffffff;
10
10
  background-color: #000000;
11
- height: 1px; /* 線の太さ */
12
- border: 1px; /* 枠の太さ */
13
- border-style: solid; /* 枠の種類 */
11
+ height: 1px;
12
+ /* 線の太さ */
13
+ border: 1px;
14
+ /* 枠の太さ */
15
+ border-style: solid;
16
+ /* 枠の種類 */
14
17
  }
15
18
 
16
19
  .error {
@@ -19,7 +22,7 @@ hr {
19
22
 
20
23
  .outarea {
21
24
  background-color: #FFFFFF;
22
- margin: 5px;
25
+ margin: 5px;
23
26
  padding: 5px;
24
27
  width: 95vw;
25
28
  height: 50vh;
@@ -28,15 +31,15 @@ hr {
28
31
 
29
32
  .inarea {
30
33
  border: thin solid #000000;
31
- margin: 5px;
34
+ margin: 5px;
32
35
  padding: 5px;
33
36
  width: 95%;
34
37
  }
35
38
 
36
39
  input.long {
37
40
  width: 90%;
38
- background-color: #FAFAFA;
39
- margin: 5px;
41
+ background-color: #FAFAFA;
42
+ margin: 5px;
40
43
  padding: 5px;
41
44
  }
42
45
 
@@ -63,12 +66,21 @@ textarea.long {
63
66
  color: black;
64
67
  }
65
68
 
69
+ .ui-autocomplete.ui-front {
70
+ max-height: 250px;
71
+ overflow-y: auto;
72
+ /* prevent horizontal scrollbar */
73
+ overflow-x: hidden;
74
+ /* add padding to account for vertical scrollbar */
75
+ z-index: 1000 !important;
76
+ }
77
+
66
78
  .ui-dialog {
67
- position: absolute;
68
- top: 0;
69
- left: 0;
70
- padding: .2em;
71
- outline: 0;
79
+ position: absolute;
80
+ top: 0;
81
+ left: 0;
82
+ padding: .2em;
83
+ outline: 0;
72
84
  }
73
85
 
74
86
  .long {
@@ -77,28 +89,36 @@ textarea.long {
77
89
 
78
90
  #setting_dialog {
79
91
  color: #796fe9;
80
- background-color: #000000;
92
+ background-color: #000000;
81
93
  }
82
94
 
83
95
  .setting_name {
84
96
  width: 200px;
85
97
  color: #796fe9;
86
- background-color: #000000;
98
+ background-color: #000000;
87
99
  }
88
100
 
89
101
  .setting_value {
90
102
  width: 300px;
91
103
  color: #796fe9;
92
- background-color: #000000;
104
+ background-color: #000000;
93
105
  }
94
106
 
95
107
  .setting_checkbox {
96
108
  color: #796fe9;
97
- background-color: #000000;
109
+ background-color: #000000;
98
110
  }
99
111
 
100
112
  ul.log {
101
- list-style-type: decimal;
113
+ list-style-type: decimal;
102
114
  font-size: 12px;
103
115
  color: #5d0a94;
116
+ }
117
+
118
+ input[type="search"] {
119
+ -webkit-appearance: searchfield;
120
+ }
121
+
122
+ input[type="search"]::-webkit-search-cancel-button {
123
+ -webkit-appearance: searchfield-cancel-button;
104
124
  }
File without changes
@@ -11,15 +11,15 @@
11
11
  <script src="https://ajax.googleapis.com/ajax/libs/jqueryui/1.12.1/jquery-ui.min.js"></script>
12
12
  <link rel="stylesheet" href="https://ajax.googleapis.com/ajax/libs/jqueryui/1.12.1/themes/smoothness/jquery-ui.css">
13
13
 
14
- <script src="http://localhost:53492/js/main.js"></script>
15
- <link rel="stylesheet" href="http://localhost:53492/css/index.css" type="text/css">
14
+ <script src="http://localhost:58656/js/main.js"></script>
15
+ <link rel="stylesheet" href="http://localhost:58656/css/index.css" type="text/css">
16
16
  </head>
17
17
 
18
18
  <body>
19
19
  <div id="msg_dialog" style="display:none;">
20
20
  <div id="msg_text">message</div>
21
21
  </div>
22
- <h4>GrepFind</h4>
22
+ <h4>RubyAppBase</h4>
23
23
  <hr>
24
24
  <table>
25
25
  <tr>
@@ -39,21 +39,21 @@
39
39
  </table>
40
40
 
41
41
  <div id="dialog1" style="display:none;">
42
- <input class="inarea" type="text" name="search_str" id="search_str">
42
+ <input class="inarea" type="search" name="search_str" id="search_str">
43
43
  </div>
44
44
  <table>
45
45
  <tr>
46
- <td class="long"><input class="inarea" type="text" id="upFile" name="upFile"></td>
46
+ <td class="long"><input class="inarea" type="search" id="upFile" name="upFile"></td>
47
47
  <td><input type="button" id="select_file" value="ファイル選択" /></td>
48
48
  </tr>
49
49
  </table>
50
50
 
51
51
  <div id="dialog2" style="display:none;">
52
- <input class="inarea" type="text" name="search_str2" id="search_str2">
52
+ <input class="inarea" type="search" name="search_str2" id="search_str2">
53
53
  </div>
54
54
  <table>
55
55
  <tr>
56
- <td class="long"><input class="inarea" type="text" id="upDir" name="upDir"></td>
56
+ <td class="long"><input class="inarea" type="search" id="upDir" name="upDir"></td>
57
57
  <td><input type="button" id="select_dir" value="フォルダ選択" /></td>
58
58
  </tr>
59
59
  </table>
File without changes
@@ -3,26 +3,35 @@
3
3
  var $ws = null;
4
4
  var $auto_scroll = true;
5
5
  var dialog = null;
6
+ var dialog_timeout = null;
6
7
 
7
- function open_dialog(msg) {
8
+ function open_dialog(msg, timeout = 0) {
8
9
  console.log("msg=" + msg);
9
10
  $("#msg_text").html(msg);
10
- $("#msg_dialog").dialog({
11
+ d = $("#msg_dialog").dialog({
11
12
  modal: true
12
13
  , show: "slide" //表示時のアニメーション
13
14
  , hide: "slide" //閉じた時のアニメーション
14
15
  , title: "Message" //ダイアログのタイトル
15
- , width: 400 //ダイアログの横幅
16
- , height: 200 //ダイアログの高さ
16
+ , width: 500 //ダイアログの横幅
17
+ , height: 300 //ダイアログの高さ
17
18
  , resizable: true //リサイズ可
18
19
  , closeOnEscape: false //[ESC]キーで閉じられなくする
19
20
  , draggable: true //ダイアログの移動を可に
20
21
  , buttons: {
21
22
  "OK": function () { //Cancelボタン
23
+ if (dialog_timeout != null) {
24
+ clearTimeout(dialog_timeout);
25
+ }
22
26
  $(this).dialog("close");
23
27
  }
24
28
  }
25
29
  });
30
+ if (timeout != 0) {
31
+ dialog_timeout = setTimeout(function () {
32
+ d.dialog("close");
33
+ }, timeout);
34
+ }
26
35
  }
27
36
 
28
37
  function open_dialog_org(msg) {
@@ -58,13 +67,18 @@ function server_connect(url) {
58
67
 
59
68
  if (evt.data.match(/^startup:/)) {
60
69
  file_name = evt.data.replace(/^startup:/, "");
61
- //alert(file_name);
62
70
  }
63
71
  else if (evt.data.match(/^app_end:normal/)) {
64
72
  open_dialog("終了しました");
65
73
  }
74
+ else if (evt.data.match(/^app_end:stop/)) {
75
+ open_dialog("中止しました");
76
+ }
66
77
  else if (evt.data.match(/^app_end:error/)) {
67
78
  open_dialog("<font color='red'>エラーが発生しました</font>");
79
+ }
80
+ else if (evt.data.match(/^popup:/)) {
81
+ open_dialog(evt.data.replace(/^popup:/, ""), 3000);
68
82
  } else {
69
83
  var log = "<li>" + evt.data + "</li>";
70
84
  $('#log').append(log);
@@ -101,7 +115,7 @@ function autocomp(id, file_kind) {
101
115
  },
102
116
  source: function (req, resp) {
103
117
  $.ajax({
104
- url: "http://localhost:53492/search?path=" + $("#" + id).val() + "&kind=" + file_kind,
118
+ url: "http://localhost:58656/search?path=" + $("#" + id).val() + "&kind=" + file_kind,
105
119
  type: "GET",
106
120
  cache: false,
107
121
  dataType: "json",
@@ -123,6 +137,38 @@ function autocomp(id, file_kind) {
123
137
  });
124
138
  }
125
139
 
140
+ function autocomp_history(id, file_name) {
141
+ $("#" + id).autocomplete({
142
+ autoFocus: true,
143
+ minLength: 0,
144
+ delay: 0,
145
+ select: function (event, ui) {
146
+ jQuery("#" + id).val(ui.item.value);
147
+ $(this).keydown();
148
+ },
149
+ source: function (req, resp) {
150
+ $.ajax({
151
+ url: "http://localhost:58656/history/" + file_name,
152
+ type: "POST",
153
+ cache: false,
154
+ dataType: "json",
155
+ data: {
156
+ param1: req.term
157
+ },
158
+ success: function (o) {
159
+ resp(o);
160
+ },
161
+ error: function (xhr, ts, err) {
162
+ resp(['']);
163
+ }
164
+ });
165
+
166
+ }
167
+ }).focus(function () {
168
+ $(this).keydown();
169
+ });
170
+ }
171
+
126
172
  function select_file_dialog(search_id, file_kind, dialog_id, select_file, file_name) {
127
173
  $("#" + select_file).click(function () {
128
174
  autocomp(search_id, file_kind);
@@ -163,7 +209,7 @@ function setting_dialog(open_id, dialog_id, json_file) {
163
209
  if (s[i].type == "input") {
164
210
  var h = "<table><tr>"
165
211
  + "<td class='setting_name'>" + s[i].description + "</td>"
166
- + "<td><input class='setting_value' type='text' " + "id=" + s[i].name + "_value " + "value=" + s[i].value + ">"
212
+ + "<td><input class='setting_value' type='text' " + "id=" + s[i].name + "_value " + "value=" + "'" + s[i].value + "'" + ">"
167
213
  + "</td></tr></table>"
168
214
  $("dl#wrap").append(h);
169
215
  } else if (s[i].type == "checkbox") {
@@ -276,20 +322,26 @@ function openFile(file) {
276
322
 
277
323
  // 起動時の処理
278
324
  $(document).ready(function () {
325
+
279
326
  // サーバに接続
280
- server_connect("ws://localhost:53492/wsserver")
327
+ server_connect("ws://localhost:58656/wsserver")
328
+ window.onload = function (e) {
329
+ // サーバに接続
330
+ //server_connect("ws://localhost:58656/wsserver")
331
+ }
332
+
281
333
  // ウインドウサイズ
282
334
  var width = 800;
283
335
  var height = 600;
284
336
  $(window).resize(function () {
285
- $(".outarea").height($(window).height() - 300);
337
+ $(".outarea").height($(window).height() - 220);
286
338
  });
287
339
  // ウインドウの位置
288
340
  $(function () {
289
341
  window.resizeTo(width, height);
290
342
  window.moveTo((window.screen.width / 2) - (width / 2), (screen.height / 2) - (height / 2));
291
343
  //window.moveTo(0,0);
292
- $(".outarea").height($(window).height() - 300);
344
+ $(".outarea").height($(window).height() - 220);
293
345
  });
294
346
 
295
347
  $('.outarea').scroll(function () {
@@ -322,5 +374,7 @@ $(document).ready(function () {
322
374
 
323
375
  setting_dialog("setting", "setting_dialog", "config/setting.json");
324
376
 
377
+ autocomp_history("upFile", "history.json")
378
+
325
379
  });
326
380
 
@@ -10,8 +10,16 @@ class MyApp < AppMainBase
10
10
  argv.each do |v|
11
11
  yield v if block_given?
12
12
  end
13
+
14
+ # Browserにメッセージ送信
15
+ app_send("popup:start app #{argv[0]}")
16
+
17
+ # 履歴の保存
18
+ add_history("history.json", argv[0])
19
+
13
20
  while true
14
21
  yield Time.now.to_s if block_given?
22
+ puts Time.now.to_s
15
23
  yield @config["name1"]
16
24
  sleep 1
17
25
  break if @abort
@@ -5,6 +5,17 @@ class AppMainBase
5
5
  @aboet = false
6
6
  @exec = false
7
7
  @suspend = false
8
+ @ws = nil
9
+ end
10
+
11
+ def app_send(str)
12
+ if @ws != nil
13
+ @ws.send(str)
14
+ end
15
+ end
16
+
17
+ def set_ws(ws)
18
+ @ws = ws
8
19
  end
9
20
 
10
21
  def set_config(config)
@@ -27,6 +38,26 @@ class AppMainBase
27
38
  def resume()
28
39
  @suspend = false
29
40
  end
41
+
42
+ # 履歴の保存
43
+ def add_history(file, history_data, max = 10)
44
+ begin
45
+ buf = File.read "#{$home_dir}history/#{file}"
46
+ rescue
47
+ buf = ""
48
+ end
49
+ data = eval(buf)
50
+ if data == nil
51
+ data = []
52
+ end
53
+ if history_data.to_s != ""
54
+ data.prepend history_data
55
+ end
56
+ data = data.uniq[0..max - 1]
57
+ File.open("#{$home_dir}history/#{file}", "w") do |f|
58
+ f.write JSON.pretty_generate data
59
+ end
60
+ end
30
61
  end
31
62
 
32
63
  require "app_load.rb"
@@ -10,6 +10,53 @@ require "kconv"
10
10
  require "json"
11
11
  require "facter"
12
12
 
13
+ # ログ出力
14
+ module Output
15
+ def self.console_and_file(output_file, stdout = true)
16
+ begin
17
+ defout = File.new(output_file, "a+")
18
+ rescue
19
+ puts $!
20
+ puts $@
21
+ return nil
22
+ end
23
+ class << defout
24
+ alias_method :write_org, :write
25
+
26
+ def initialize(stdout)
27
+ @stdout = false
28
+ end
29
+
30
+ attr_accessor :stdout
31
+
32
+ def puts(str)
33
+ STDOUT.write(str.to_s + "\n") if @stdout
34
+ self.write_org(str.to_s + "\n")
35
+ self.flush
36
+ end
37
+
38
+ def write(str)
39
+ STDOUT.write(str) if @stdout
40
+ self.write_org(str)
41
+ self.flush
42
+ end
43
+ end
44
+ $stdout = defout
45
+ $stdout.stdout = stdout
46
+ end
47
+ end
48
+
49
+ # ディレクトリ移動
50
+ dir = File.dirname(File.expand_path(__FILE__))
51
+ FileUtils.cd dir
52
+
53
+ # ディレクトリ作成
54
+ $home_dir = ENV["HOME"] + "/" + dir.split("/")[-1] + "/"
55
+ puts "home_dir=#{$home_dir}"
56
+ FileUtils.mkdir_p("#{$home_dir}/logs")
57
+ FileUtils.mkdir_p("#{$home_dir}/history")
58
+ Output.console_and_file("#{$home_dir}/logs/app.log", true)
59
+
13
60
  # 空きポートを取得
14
61
  def get_unused_port
15
62
  s = TCPServer.open(0)
@@ -33,26 +80,45 @@ buf.gsub!(/localhost:[0-9]+\//, "localhost:#{port}/")
33
80
  File.binwrite("js/main.js", buf)
34
81
 
35
82
  # index.htaの編集
36
- buf = File.binread("index.html").toutf8
83
+ buf = File.binread("html/index.html").toutf8
37
84
  buf.gsub!(/localhost:[0-9]+\//, "localhost:#{port}/")
38
- File.binwrite("index.html", buf)
39
-
40
- Thread.start {
41
- puts "start browser"
42
- json_file = File.dirname(File.expand_path(__FILE__)) + "/config/browser.json"
43
- json = JSON.parse(File.read json_file)
44
- puts json
45
- kernel = Facter.value(:kernel)
46
- if kernel == "windows"
47
- browser = json["chrome_win"]
48
- elsif kernel == "Linux"
49
- browser = json["chrome_linux"]
50
- else
51
- browser = json["chrome_win"]
52
- end
53
- browser += " -app=http://localhost:#{port}"
54
- puts browser
55
- system browser
56
- }
85
+ File.binwrite("html/index.html", buf)
57
86
 
58
- Rack::Server.start
87
+ begin
88
+ Thread.start {
89
+ puts "wait start web server"
90
+ while true
91
+ begin
92
+ s = TCPSocket.open("localhost", port)
93
+ s.close
94
+ break
95
+ rescue
96
+ puts $!
97
+ sleep 0.1
98
+ end
99
+ end
100
+
101
+ puts "start browser"
102
+ json_file = "#{$home_dir}/config/browser.json"
103
+ json = JSON.parse(File.read json_file)
104
+ puts json
105
+ kernel = Facter.value(:kernel)
106
+ if kernel == "windows"
107
+ browser = json["chrome_win"]
108
+ elsif kernel == "Linux"
109
+ browser = json["chrome_linux"]
110
+ else
111
+ browser = json["chrome_win"]
112
+ end
113
+ browser += " -app=http://localhost:#{port}"
114
+ puts browser
115
+ system browser
116
+ }
117
+
118
+ # start web server
119
+ Rack::Server.start
120
+ rescue
121
+ puts $!
122
+ puts $@
123
+ exit
124
+ end
@@ -1,6 +1,7 @@
1
1
  require "./server_app_base"
2
2
  require "json"
3
3
  require "cgi"
4
+ require "thread"
4
5
 
5
6
  def config_json_hash(json)
6
7
  config = {}
@@ -10,8 +11,23 @@ def config_json_hash(json)
10
11
  return config
11
12
  end
12
13
 
14
+ $ws_exit_thread = nil
15
+
13
16
  class WsServer < Sinatra::Base
14
- $ws_list = []
17
+ def initialize
18
+ super
19
+ @ws_list = []
20
+ @ws_lock = Mutex.new
21
+ end
22
+
23
+ def ws_send(str)
24
+ @ws_lock.synchronize do
25
+ if @ws_list[0] != nil
26
+ @ws_list[0].send(str)
27
+ end
28
+ end
29
+ end
30
+
15
31
  json_config = nil
16
32
  exec_thread = nil
17
33
  get "" do
@@ -20,28 +36,38 @@ class WsServer < Sinatra::Base
20
36
  else
21
37
  request.websocket do |ws|
22
38
  ws.onopen do
23
- ws.send("startup:#{$startup_file}")
24
- $ws_list << ws
39
+ puts "ws.open"
40
+ @ws_lock.synchronize do
41
+ @ws_list << ws
42
+ $app.set_ws(ws)
43
+ pp "ws=#{ws}"
44
+ end
45
+ ws_send("startup:#{$startup_file}")
46
+ puts "ws_exit_thread=#{$ws_exit_thread}"
47
+ if $ws_exit_thread != nil
48
+ puts "ws_exit_thread kill"
49
+ Thread.kill $ws_exit_thread
50
+ end
25
51
  end
26
52
  ws.onmessage do |msg|
27
53
  puts msg
54
+ json = JSON.parse(File.read("#{$home_dir}/config/setting.json"))
55
+ json_config = config_json_hash(json)
56
+ $app.set_config(json_config)
28
57
  if msg =~ /^exec:/
29
58
  if exec_thread == nil
30
- json = JSON.parse(File.read("config/setting.json"))
31
- json_config = config_json_hash(json)
32
- $app.set_config(json_config)
33
59
  argv = msg.gsub(/^exec:/, "")
34
60
  exec_thread = Thread.new {
35
61
  begin
36
62
  $app.start(argv.split(",")) do |out|
37
- ws.send(out)
63
+ ws_send(out)
38
64
  end
39
- ws.send("app_end:normal")
65
+ ws_send("app_end:normal")
40
66
  rescue
41
67
  puts $!
42
68
  puts $@
43
69
  puts "app_end:err"
44
- ws.send("app_end:error")
70
+ ws_send("app_end:error")
45
71
  ensure
46
72
  puts "exit thread"
47
73
  exec_thread = nil
@@ -49,11 +75,13 @@ class WsServer < Sinatra::Base
49
75
  }
50
76
  else
51
77
  puts "app_end:err"
52
- ws.send("app_end:error")
78
+ ws_send("app_end:error")
53
79
  end
54
80
  end
55
81
  if msg =~ /^stop/
56
82
  if exec_thread
83
+ Thread.kill exec_thread
84
+ ws_send("app_end:stop")
57
85
  $app.stop
58
86
  end
59
87
  end
@@ -70,7 +98,7 @@ class WsServer < Sinatra::Base
70
98
  if msg =~ /^setting:/
71
99
  json_string = msg.gsub(/^setting:/, "")
72
100
  json = JSON.parse(json_string)
73
- File.open("config/setting.json", "w") do |w|
101
+ File.open("#{$home_dir}/config/setting.json", "w") do |w|
74
102
  w.puts JSON.pretty_generate(json)
75
103
  end
76
104
  json_config = config_json_hash(json)
@@ -83,23 +111,27 @@ class WsServer < Sinatra::Base
83
111
  }
84
112
  end
85
113
 
114
+ # アプリケーション終了
86
115
  if msg == "exit"
87
- unless ENV["OCRA"] == "true"
88
- halt
89
- #exit
90
- end
116
+ #halt
117
+ exit
91
118
  end
92
119
  end
120
+
121
+ # close websocket
93
122
  ws.onclose do
94
123
  puts "websocket closed"
95
- $ws_list.delete(ws)
96
- puts $ws_list.size
97
- if $ws_list.size == 0
98
- puts ENV["OCRA"]
99
- unless ENV["OCRA"] == "true"
124
+ @ws_lock.synchronize do
125
+ @ws_list.delete(ws)
126
+ end
127
+ puts @ws_list.size
128
+ if @ws_list.size == 0
129
+ $ws_exit_thread = Thread.start {
130
+ sleep 1
100
131
  #halt
101
132
  exit
102
- end
133
+ }
134
+ puts "ws_exit_thread=#{$ws_exit_thread}"
103
135
  end
104
136
  end
105
137
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: browser_app_base
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.8
4
+ version: 0.1.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - masataka kuwayama
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2021-11-21 00:00:00.000000000 Z
11
+ date: 2022-01-26 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: sinatra
@@ -99,6 +99,7 @@ email:
99
99
  - masataka.kuwayama@gmail.com
100
100
  executables:
101
101
  - create_browser_app.rb
102
+ - start_sample.rb
102
103
  extensions: []
103
104
  extra_rdoc_files: []
104
105
  files:
@@ -110,6 +111,7 @@ files:
110
111
  - README.md
111
112
  - Rakefile
112
113
  - bin/create_browser_app.rb
114
+ - bin/start_sample.rb
113
115
  - browser_app_base.gemspec
114
116
  - lib/browser_app_base.rb
115
117
  - lib/browser_app_base/version.rb
@@ -118,7 +120,9 @@ files:
118
120
  - lib/template/config/browser.json
119
121
  - lib/template/config/setting.json
120
122
  - lib/template/css/index.css
121
- - lib/template/index.html
123
+ - lib/template/history/history.json
124
+ - lib/template/html/index.html
125
+ - lib/template/html/test.html
122
126
  - lib/template/js/main.js
123
127
  - lib/template/my_app_sample.rb
124
128
  - lib/template/server.rb