browser_app_base 0.0.8 → 0.1.2

Sign up to get free protection for your applications and to get access to all the features.
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