browser_app_base 0.0.5 → 0.0.9

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: 3565687a000a2d7a0636d2ac47c09de24d87cfe1554777b58d8f9d9ab494102d
4
- data.tar.gz: a305213755edff63ab70edff0f2011d52c33ee6fd53b9aaddce80865440107c3
3
+ metadata.gz: d8f803f44d98065ce973ec89c418d7d9d8fb75ce8c1f6dc74f8e449681a3a0f5
4
+ data.tar.gz: 0bf164a5280e040b5efa5fe0221ae17f19d77b4569c3c4db5e4893d19a5e0efb
5
5
  SHA512:
6
- metadata.gz: f2f2cb63d6ff01e6bb39731fd36944a8a4ff96c9b5370ed9b386383bc6c67fe55586d1e6f278d8af17713b542079f1850de0afd820c9b78357d7afc4debb63d8
7
- data.tar.gz: 200b7d9a67ef7421f52a2d3887b91d3d9c5ab99eda27ccebbf1725718204d25945bc0f31679811d0d4e959561ebed2906de8b98900c9272f80196b6fa9f7640a
6
+ metadata.gz: 881fd8551b75678a1825a1cb227918f22ce9e6db9377e940bd7b25d04d7827d491c4f42c0c4da372607666533ada91239fb4f79f3792b3252dedf3c589424de4
7
+ data.tar.gz: 1c630a5c7affe753747bc2aee0789b384249676f6a90a036fce54471084e0bf471c2c88bdd701e13851f5f7d33f53e8360a52e6898a29bc09e9f045183791b9d
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
@@ -61,6 +61,47 @@ ui application sample
61
61
  $ cd ~/test/
62
62
  $ ruby start.rb
63
63
 
64
+ ## browser setting
65
+
66
+ config/browser.json
67
+ Set the path for your Windows or Linux Chrome browser
68
+
69
+ ```json
70
+ {
71
+ "chrome_win": "start chrome",
72
+ "chrome_linux": "/bin/google-chrome"
73
+ }
74
+ ```
75
+
76
+ ## Send a message from your browser application to your ruby application
77
+
78
+ Use the send_message function
79
+
80
+ main.js sample
81
+ ```javascript
82
+ $("#exec").click(function () {
83
+ send_message("exec:" + $("#upFile").val());
84
+ });
85
+
86
+ ```
87
+
88
+ ## Send a message from the ruby application to the browser application
89
+
90
+ Use the app_send function
91
+
92
+ my_app_sample.rb sample
93
+ ```ruby
94
+ class MyApp < AppMainBase
95
+ def start(argv)
96
+ # popup message
97
+ app_send("popup:message string")
98
+
99
+ # log message
100
+ yield "log message"
101
+ end
102
+ end
103
+ ```
104
+
64
105
  ## Development
65
106
 
66
107
  To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and the created tag, and push the `.gem` file to [rubygems.org](https://rubygems.org).
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module BrowserAppBase
4
- VERSION = "0.0.5"
4
+ VERSION = "0.0.9"
5
5
  end
@@ -1,50 +1,50 @@
1
- [
2
- {
3
- "name": "name1",
4
- "value": "value1",
5
- "type": "input",
6
- "select": "",
7
- "description": "設定項目1"
8
- },
9
- {
10
- "name": "name2",
11
- "value": true,
12
- "type": "checkbox",
13
- "select": "",
14
- "description": "有効にする場合はチェック"
15
- },
16
- {
17
- "name": "name3",
18
- "value": "1",
19
- "type": "select",
20
- "select": [
21
- "1",
22
- "2",
23
- "3",
24
- "4",
25
- "5"
26
- ],
27
- "description": "選択項目"
28
- },
29
- {
30
- "name": "name4",
31
- "value": "value4",
32
- "type": "input",
33
- "select": "",
34
- "description": "設定項目4"
35
- },
36
- {
37
- "name": "name5",
38
- "value": "value5",
39
- "type": "input",
40
- "select": "",
41
- "description": "設定項目5"
42
- },
43
- {
44
- "name": "name6",
45
- "value": "value6",
46
- "type": "input",
47
- "select": "",
48
- "description": "設定項目6"
49
- }
50
- ]
1
+ [
2
+ {
3
+ "name": "name1",
4
+ "value": "value1",
5
+ "type": "input",
6
+ "select": "",
7
+ "description": "設定項目1"
8
+ },
9
+ {
10
+ "name": "name2",
11
+ "value": true,
12
+ "type": "checkbox",
13
+ "select": "",
14
+ "description": "有効にする場合はチェック"
15
+ },
16
+ {
17
+ "name": "name3",
18
+ "value": "1",
19
+ "type": "select",
20
+ "select": [
21
+ "1",
22
+ "2",
23
+ "3",
24
+ "4",
25
+ "5"
26
+ ],
27
+ "description": "選択項目"
28
+ },
29
+ {
30
+ "name": "name4",
31
+ "value": "value4",
32
+ "type": "input",
33
+ "select": "",
34
+ "description": "設定項目4"
35
+ },
36
+ {
37
+ "name": "name5",
38
+ "value": "value5",
39
+ "type": "input",
40
+ "select": "",
41
+ "description": "設定項目5"
42
+ },
43
+ {
44
+ "name": "name6",
45
+ "value": "value6",
46
+ "type": "input",
47
+ "select": "",
48
+ "description": "設定項目6"
49
+ }
50
+ ]
@@ -30,6 +30,43 @@ get "/config/*.*" do |file, ext|
30
30
  File.read "config/#{file}.#{ext}"
31
31
  end
32
32
 
33
+ post "/history/*.*" do |file, ext|
34
+ content_type "text/json", :charset => "utf-8"
35
+ puts "#{file}.#{ext}"
36
+ p = params[:param1]
37
+ buf = File.read "history/#{file}.#{ext}"
38
+ data = eval(buf)
39
+ if data != nil
40
+ if p != ""
41
+ JSON.generate data.find_all { |d| d =~ Regexp.new(p) }
42
+ else
43
+ JSON.generate data
44
+ end
45
+ end
46
+ end
47
+
48
+ get "/open_dialog" do
49
+ dialog_html = <<'EOS'
50
+ <!DOCTYPE html>
51
+ <html>
52
+ <head>
53
+ <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
54
+ <title>Message Dialog</title>
55
+ <style type="text/css">
56
+ <!--
57
+ body {
58
+ color: #000000;
59
+ background-color: #ffffff;
60
+ overflow: hidden;
61
+ font-size: 12px;
62
+ }
63
+ -->
64
+ </style>
65
+ </head>
66
+ EOS
67
+ dialog_html += "<body>" + params["msg"] + "</body></html>"
68
+ end
69
+
33
70
  map "/search" do
34
71
  run Search
35
72
  end
@@ -52,6 +89,6 @@ configure do
52
89
 
53
90
  end
54
91
 
55
- #\ --port 52538
92
+ #\ --port 61047
56
93
 
57
94
  run Sinatra::Application
@@ -1,15 +1,19 @@
1
1
  body {
2
2
  color: #000000;
3
- background-color: #cac3ec4f;
3
+ background-color: #cac3ec4f;
4
4
  overflow: hidden;
5
+ font-size: 12px;
5
6
  }
6
7
 
7
8
  hr {
8
9
  color: #ffffff;
9
10
  background-color: #000000;
10
- height: 1px; /* 線の太さ */
11
- border: 1px; /* 枠の太さ */
12
- border-style: solid; /* 枠の種類 */
11
+ height: 1px;
12
+ /* 線の太さ */
13
+ border: 1px;
14
+ /* 枠の太さ */
15
+ border-style: solid;
16
+ /* 枠の種類 */
13
17
  }
14
18
 
15
19
  .error {
@@ -18,7 +22,7 @@ hr {
18
22
 
19
23
  .outarea {
20
24
  background-color: #FFFFFF;
21
- margin: 5px;
25
+ margin: 5px;
22
26
  padding: 5px;
23
27
  width: 95vw;
24
28
  height: 50vh;
@@ -27,15 +31,15 @@ hr {
27
31
 
28
32
  .inarea {
29
33
  border: thin solid #000000;
30
- margin: 5px;
34
+ margin: 5px;
31
35
  padding: 5px;
32
36
  width: 95%;
33
37
  }
34
38
 
35
39
  input.long {
36
40
  width: 90%;
37
- background-color: #FAFAFA;
38
- margin: 5px;
41
+ background-color: #FAFAFA;
42
+ margin: 5px;
39
43
  padding: 5px;
40
44
  }
41
45
 
@@ -49,8 +53,8 @@ textarea.long {
49
53
  }
50
54
 
51
55
  .ui-autocomplete {
52
- max-height: 200px;
53
- max-width: 500px;
56
+ max-height: 45vh;
57
+ max-width: 90wh;
54
58
  overflow-y: auto;
55
59
  overflow-x: auto;
56
60
  padding-right: 10px;
@@ -63,11 +67,11 @@ textarea.long {
63
67
  }
64
68
 
65
69
  .ui-dialog {
66
- position: absolute;
67
- top: 0;
68
- left: 0;
69
- padding: .2em;
70
- outline: 0;
70
+ position: absolute;
71
+ top: 0;
72
+ left: 0;
73
+ padding: .2em;
74
+ outline: 0;
71
75
  }
72
76
 
73
77
  .long {
@@ -76,28 +80,36 @@ textarea.long {
76
80
 
77
81
  #setting_dialog {
78
82
  color: #796fe9;
79
- background-color: #000000;
83
+ background-color: #000000;
80
84
  }
81
85
 
82
86
  .setting_name {
83
87
  width: 200px;
84
88
  color: #796fe9;
85
- background-color: #000000;
89
+ background-color: #000000;
86
90
  }
87
91
 
88
92
  .setting_value {
89
93
  width: 300px;
90
94
  color: #796fe9;
91
- background-color: #000000;
95
+ background-color: #000000;
92
96
  }
93
97
 
94
98
  .setting_checkbox {
95
99
  color: #796fe9;
96
- background-color: #000000;
100
+ background-color: #000000;
97
101
  }
98
102
 
99
103
  ul.log {
100
- list-style-type: decimal;
101
- font-size: 10px;
104
+ list-style-type: decimal;
105
+ font-size: 12px;
102
106
  color: #5d0a94;
107
+ }
108
+
109
+ input[type="search"] {
110
+ -webkit-appearance: searchfield;
111
+ }
112
+
113
+ input[type="search"]::-webkit-search-cancel-button {
114
+ -webkit-appearance: searchfield-cancel-button;
103
115
  }
File without changes
@@ -11,12 +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:52538/js/main.js"></script>
15
- <link rel="stylesheet" href="http://localhost:52538/css/index.css" type="text/css">
14
+ <script src="http://localhost:61047/js/main.js"></script>
15
+ <link rel="stylesheet" href="http://localhost:61047/css/index.css" type="text/css">
16
16
  </head>
17
17
 
18
18
  <body>
19
- <h3>サンプル</h3>
19
+ <div id="msg_dialog" style="display:none;">
20
+ <div id="msg_text">message</div>
21
+ </div>
22
+ <h4>RubyAppBase</h4>
20
23
  <hr>
21
24
  <table>
22
25
  <tr>
@@ -40,7 +43,7 @@
40
43
  </div>
41
44
  <table>
42
45
  <tr>
43
- <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>
44
47
  <td><input type="button" id="select_file" value="ファイル選択" /></td>
45
48
  </tr>
46
49
  </table>
@@ -50,7 +53,7 @@
50
53
  </div>
51
54
  <table>
52
55
  <tr>
53
- <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>
54
57
  <td><input type="button" id="select_dir" value="フォルダ選択" /></td>
55
58
  </tr>
56
59
  </table>
@@ -2,6 +2,50 @@
2
2
 
3
3
  var $ws = null;
4
4
  var $auto_scroll = true;
5
+ var dialog = null;
6
+
7
+ function open_dialog(msg) {
8
+ console.log("msg=" + msg);
9
+ $("#msg_text").html(msg);
10
+ $("#msg_dialog").dialog({
11
+ modal: true
12
+ , show: "slide" //表示時のアニメーション
13
+ , hide: "slide" //閉じた時のアニメーション
14
+ , title: "Message" //ダイアログのタイトル
15
+ , width: 400 //ダイアログの横幅
16
+ , height: 200 //ダイアログの高さ
17
+ , resizable: true //リサイズ可
18
+ , closeOnEscape: false //[ESC]キーで閉じられなくする
19
+ , draggable: true //ダイアログの移動を可に
20
+ , buttons: {
21
+ "OK": function () { //Cancelボタン
22
+ $(this).dialog("close");
23
+ }
24
+ }
25
+ });
26
+ }
27
+
28
+ function open_dialog_org(msg) {
29
+ var top = window.screenTop + 10;
30
+ var left = window.screenLeft + 10;
31
+ if (dialog != null) {
32
+ dialog.close();
33
+ }
34
+ var dialog = window.open(
35
+ "/open_dialog?msg=" + msg,
36
+ "pop",
37
+ "width=300, height=100, left=" + left + ", top=" + top
38
+ );
39
+ console.log("open dialog dialog=" + dialog);
40
+ if (dialog == null) {
41
+ console.log("open dialog retry");
42
+ setTimeout(function () {
43
+ open_dialog(msg);
44
+ }, 1000);
45
+ } else {
46
+ dialog.focus();
47
+ }
48
+ }
5
49
 
6
50
  function server_connect(url) {
7
51
  var ws = new WebSocket(url);
@@ -11,9 +55,18 @@ function server_connect(url) {
11
55
  };
12
56
  ws.onmessage = function (evt) {
13
57
  //alert(evt.data);
58
+
14
59
  if (evt.data.match(/^startup:/)) {
15
60
  file_name = evt.data.replace(/^startup:/, "");
16
- //alert(file_name);
61
+ }
62
+ else if (evt.data.match(/^app_end:normal/)) {
63
+ open_dialog("終了しました");
64
+ }
65
+ else if (evt.data.match(/^app_end:error/)) {
66
+ open_dialog("<font color='red'>エラーが発生しました</font>");
67
+ }
68
+ else if (evt.data.match(/^popup:/)) {
69
+ open_dialog(evt.data.replace(/^popup:/, ""));
17
70
  } else {
18
71
  var log = "<li>" + evt.data + "</li>";
19
72
  $('#log').append(log);
@@ -43,14 +96,14 @@ function autocomp(id, file_kind) {
43
96
  minLength: 0,
44
97
  delay: 0,
45
98
  select: function (event, ui) {
46
- console.log(ui.item.value);
99
+ //console.log(ui.item.value);
47
100
  jQuery("#" + id).val(ui.item.value);
48
101
  //jQuery(this).autocomplete("search", "");
49
102
  $(this).keydown();
50
103
  },
51
104
  source: function (req, resp) {
52
105
  $.ajax({
53
- url: "http://localhost:52538/search?path=" + $("#" + id).val() + "&kind=" + file_kind,
106
+ url: "http://localhost:61047/search?path=" + $("#" + id).val() + "&kind=" + file_kind,
54
107
  type: "GET",
55
108
  cache: false,
56
109
  dataType: "json",
@@ -72,11 +125,44 @@ function autocomp(id, file_kind) {
72
125
  });
73
126
  }
74
127
 
128
+ function autocomp_history(id, file_name) {
129
+ $("#" + id).autocomplete({
130
+ autoFocus: true,
131
+ minLength: 0,
132
+ delay: 0,
133
+ select: function (event, ui) {
134
+ jQuery("#" + id).val(ui.item.value);
135
+ $(this).keydown();
136
+ },
137
+ source: function (req, resp) {
138
+ $.ajax({
139
+ url: "http://localhost:61047/history/" + file_name,
140
+ type: "POST",
141
+ cache: false,
142
+ dataType: "json",
143
+ data: {
144
+ param1: req.term
145
+ },
146
+ success: function (o) {
147
+ resp(o);
148
+ },
149
+ error: function (xhr, ts, err) {
150
+ resp(['']);
151
+ }
152
+ });
153
+
154
+ }
155
+ }).focus(function () {
156
+ $(this).keydown();
157
+ });
158
+ }
159
+
75
160
  function select_file_dialog(search_id, file_kind, dialog_id, select_file, file_name) {
76
161
  $("#" + select_file).click(function () {
77
162
  autocomp(search_id, file_kind);
78
163
  $(".ui-autocomplete").css("z-index", 1000);
79
- $("#" + search_id).val("/");
164
+ console.log("name=" + $("#" + file_name).val());
165
+ $("#" + search_id).val($("#" + file_name).val());
80
166
  $("#" + dialog_id).dialog({
81
167
  modal: true
82
168
  , show: "slide" //表示時のアニメーション
@@ -139,7 +225,7 @@ function setting_dialog(open_id, dialog_id, json_file) {
139
225
  h += "</tr></table>";
140
226
  $("dl#wrap").append(h);
141
227
  } else {
142
- console.log("type=" + s[i].type);
228
+ //console.log("type=" + s[i].type);
143
229
  }
144
230
  }
145
231
  });
@@ -159,7 +245,7 @@ function setting_dialog(open_id, dialog_id, json_file) {
159
245
  var json_data = []
160
246
  $.getJSON(json_file, function (s) {
161
247
  for (var i in s) {
162
- console.log(s[i].name);
248
+ //console.log(s[i].name);
163
249
  if (s[i].type == "input") {
164
250
  var data = {};
165
251
  data["name"] = s[i].name;
@@ -190,7 +276,7 @@ function setting_dialog(open_id, dialog_id, json_file) {
190
276
  data["description"] = s[i].description;
191
277
  json_data.push(data);
192
278
  } else {
193
- console.log("type=" + s[i].type);
279
+ //console.log("type=" + s[i].type);
194
280
  }
195
281
  }
196
282
  $ws.send("setting:" + JSON.stringify(json_data));
@@ -218,24 +304,37 @@ function dispFile() {
218
304
  alert('選択したファイルの値は' + fName + 'です');
219
305
  }
220
306
 
307
+ function openFile(file) {
308
+ $ws.send("openfile:" + file);
309
+ }
310
+
221
311
  // 起動時の処理
222
312
  $(document).ready(function () {
223
- // サーバに接続
224
- server_connect("ws://localhost:52538/wsserver")
313
+
314
+ window.onload = function (e) {
315
+ console.log("onload");
316
+ // サーバに接続
317
+ server_connect("ws://localhost:61047/wsserver")
318
+ }
319
+
225
320
  // ウインドウサイズ
226
321
  var width = 800;
227
322
  var height = 600;
323
+ $(window).resize(function () {
324
+ $(".outarea").height($(window).height() - 220);
325
+ });
228
326
  // ウインドウの位置
229
327
  $(function () {
230
328
  window.resizeTo(width, height);
231
329
  window.moveTo((window.screen.width / 2) - (width / 2), (screen.height / 2) - (height / 2));
232
330
  //window.moveTo(0,0);
331
+ $(".outarea").height($(window).height() - 220);
233
332
  });
234
333
 
235
334
  $('.outarea').scroll(function () {
236
335
  var h = $('.outarea').get(0).scrollHeight - $('.outarea').innerHeight();
237
- console.log("scrollEnd=" + Math.abs($('.outarea').scrollTop() - h));
238
- if (Math.abs($('.outarea').scrollTop() - h) < 5) {
336
+ //console.log("scrollEnd=" + Math.abs($('.outarea').scrollTop() - h));
337
+ if (Math.abs($('.outarea').scrollTop() - h) < 30) {
239
338
  // 最後までスクロールしている
240
339
  // 自動スクロールON
241
340
  $auto_scroll = true;
@@ -262,5 +361,7 @@ $(document).ready(function () {
262
361
 
263
362
  setting_dialog("setting", "setting_dialog", "config/setting.json");
264
363
 
364
+ autocomp_history("upFile", "history.json")
365
+
265
366
  });
266
367
 
@@ -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,21 @@ class AppMainBase
27
38
  def resume()
28
39
  @suspend = false
29
40
  end
41
+
42
+ # 履歴の保存
43
+ def add_history(file, history_data)
44
+ buf = File.read "history/#{file}"
45
+ data = eval(buf)
46
+ if data == nil
47
+ data = []
48
+ end
49
+ if history_data.to_s != ""
50
+ data.prepend history_data
51
+ end
52
+ File.open("history/#{file}", "w") do |f|
53
+ f.write JSON.pretty_generate data.uniq
54
+ end
55
+ end
30
56
  end
31
57
 
32
58
  require "app_load.rb"
@@ -10,6 +10,35 @@ require "kconv"
10
10
  require "json"
11
11
  require "facter"
12
12
 
13
+ # ログ出力
14
+ module Output
15
+ def self.console_and_file(output_file)
16
+ defout = File.new(output_file, "a+")
17
+ class << defout
18
+ alias_method :write_org, :write
19
+
20
+ def puts(str)
21
+ STDOUT.write(str.to_s + "\n")
22
+ self.write_org(str.to_s + "\n")
23
+ self.flush
24
+ end
25
+
26
+ def write(str)
27
+ STDOUT.write(str)
28
+ self.write_org(str)
29
+ self.flush
30
+ end
31
+ end
32
+ $stdout = defout
33
+ end
34
+ end
35
+
36
+ Output.console_and_file("log.txt")
37
+
38
+ # ディレクトリ移動
39
+ dir = File.dirname(File.expand_path(__FILE__))
40
+ FileUtils.cd dir
41
+
13
42
  # 空きポートを取得
14
43
  def get_unused_port
15
44
  s = TCPServer.open(0)
@@ -37,22 +66,41 @@ buf = File.binread("index.html").toutf8
37
66
  buf.gsub!(/localhost:[0-9]+\//, "localhost:#{port}/")
38
67
  File.binwrite("index.html", buf)
39
68
 
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
- }
69
+ begin
70
+ Thread.start {
71
+ puts "wait start web server"
72
+ while true
73
+ begin
74
+ s = TCPSocket.open("localhost", port)
75
+ s.close
76
+ break
77
+ rescue
78
+ puts $!
79
+ sleep 0.1
80
+ end
81
+ end
57
82
 
58
- Rack::Server.start
83
+ puts "start browser"
84
+ json_file = File.dirname(File.expand_path(__FILE__)) + "/config/browser.json"
85
+ json = JSON.parse(File.read json_file)
86
+ puts json
87
+ kernel = Facter.value(:kernel)
88
+ if kernel == "windows"
89
+ browser = json["chrome_win"]
90
+ elsif kernel == "Linux"
91
+ browser = json["chrome_linux"]
92
+ else
93
+ browser = json["chrome_win"]
94
+ end
95
+ browser += " -app=http://localhost:#{port}"
96
+ puts browser
97
+ system browser
98
+ }
99
+
100
+ # start web server
101
+ Rack::Server.start
102
+ rescue
103
+ puts $!
104
+ puts $@
105
+ exit
106
+ end
@@ -1,5 +1,7 @@
1
1
  require "./server_app_base"
2
2
  require "json"
3
+ require "cgi"
4
+ require "thread"
3
5
 
4
6
  def config_json_hash(json)
5
7
  config = {}
@@ -9,8 +11,23 @@ def config_json_hash(json)
9
11
  return config
10
12
  end
11
13
 
14
+ $ws_exit_thread = nil
15
+
12
16
  class WsServer < Sinatra::Base
13
- $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
+
14
31
  json_config = nil
15
32
  exec_thread = nil
16
33
  get "" do
@@ -19,8 +36,18 @@ class WsServer < Sinatra::Base
19
36
  else
20
37
  request.websocket do |ws|
21
38
  ws.onopen do
22
- ws.send("startup:#{$startup_file}")
23
- $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
24
51
  end
25
52
  ws.onmessage do |msg|
26
53
  puts msg
@@ -31,11 +58,24 @@ class WsServer < Sinatra::Base
31
58
  $app.set_config(json_config)
32
59
  argv = msg.gsub(/^exec:/, "")
33
60
  exec_thread = Thread.new {
34
- $app.start(argv.split(",")) do |out|
35
- ws.send(out)
61
+ begin
62
+ $app.start(argv.split(",")) do |out|
63
+ ws_send(out)
64
+ end
65
+ ws_send("app_end:normal")
66
+ rescue
67
+ puts $!
68
+ puts $@
69
+ puts "app_end:err"
70
+ ws_send("app_end:error")
71
+ ensure
72
+ puts "exit thread"
73
+ exec_thread = nil
36
74
  end
37
- exec_thread = nil
38
75
  }
76
+ else
77
+ puts "app_end:err"
78
+ ws_send("app_end:error")
39
79
  end
40
80
  end
41
81
  if msg =~ /^stop/
@@ -62,24 +102,34 @@ class WsServer < Sinatra::Base
62
102
  json_config = config_json_hash(json)
63
103
  $app.set_config(json_config)
64
104
  end
105
+ if msg =~ /^openfile:/
106
+ file = msg.gsub(/^openfile:/, "")
107
+ Thread.new {
108
+ system "#{json_config["editor"]} #{CGI.unescapeHTML(file)}"
109
+ }
110
+ end
65
111
 
112
+ # アプリケーション終了
66
113
  if msg == "exit"
67
- unless ENV["OCRA"] == "true"
68
- halt
69
- #exit
70
- end
114
+ #halt
115
+ exit
71
116
  end
72
117
  end
118
+
119
+ # close websocket
73
120
  ws.onclose do
74
121
  puts "websocket closed"
75
- $ws_list.delete(ws)
76
- puts $ws_list.size
77
- if $ws_list.size == 0
78
- puts ENV["OCRA"]
79
- unless ENV["OCRA"] == "true"
122
+ @ws_lock.synchronize do
123
+ @ws_list.delete(ws)
124
+ end
125
+ puts @ws_list.size
126
+ if @ws_list.size == 0
127
+ $ws_exit_thread = Thread.start {
128
+ sleep 1
80
129
  #halt
81
130
  exit
82
- end
131
+ }
132
+ puts "ws_exit_thread=#{$ws_exit_thread}"
83
133
  end
84
134
  end
85
135
  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.5
4
+ version: 0.0.9
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-09-20 00:00:00.000000000 Z
11
+ date: 2021-12-31 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: sinatra
@@ -118,6 +118,7 @@ files:
118
118
  - lib/template/config/browser.json
119
119
  - lib/template/config/setting.json
120
120
  - lib/template/css/index.css
121
+ - lib/template/history/history.json
121
122
  - lib/template/index.html
122
123
  - lib/template/js/main.js
123
124
  - lib/template/my_app_sample.rb