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 +4 -4
- data/.vscode/launch.json +8 -2
- data/README.md +32 -3
- data/bin/start_sample.rb +39 -0
- data/lib/browser_app_base/version.rb +1 -1
- data/lib/browser_app_base.rb +12 -7
- data/lib/template/config/browser.json +2 -2
- data/lib/template/config/setting.json +2 -2
- data/lib/template/config.ru +32 -4
- data/lib/template/css/index.css +38 -18
- data/lib/template/history/history.json +0 -0
- data/lib/template/{index.html → html/index.html} +7 -7
- data/lib/template/html/test.html +0 -0
- data/lib/template/js/main.js +64 -10
- data/lib/template/my_app_sample.rb +8 -0
- data/lib/template/server_app_base.rb +31 -0
- data/lib/template/start.rb +87 -21
- data/lib/template/wsserver.rb +53 -21
- metadata +7 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 32eb1959381928c1c8be5a8760701706f771df4207232dd7a9047940a6f359a8
|
4
|
+
data.tar.gz: 38edd65c1cd9cbf4efa10a714bf1a0675fc9043642379b4c5b731e211ce3e0ad
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
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
|
8
|
+
"name": "Debug create_browser_app.rb",
|
9
9
|
"type": "Ruby",
|
10
10
|
"request": "launch",
|
11
|
-
"
|
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
|
-
|
62
|
-
|
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
|
|
data/bin/start_sample.rb
ADDED
@@ -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
|
+
}
|
data/lib/browser_app_base.rb
CHANGED
@@ -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,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": "
|
18
|
+
"value": "2",
|
19
19
|
"type": "select",
|
20
20
|
"select": [
|
21
21
|
"1",
|
data/lib/template/config.ru
CHANGED
@@ -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,
|
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
|
105
|
+
#\ --port 58656
|
78
106
|
|
79
107
|
run Sinatra::Application
|
data/lib/template/css/index.css
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
body {
|
2
2
|
color: #000000;
|
3
|
-
|
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
|
-
|
13
|
-
border
|
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
|
-
|
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
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
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
|
-
|
92
|
+
background-color: #000000;
|
81
93
|
}
|
82
94
|
|
83
95
|
.setting_name {
|
84
96
|
width: 200px;
|
85
97
|
color: #796fe9;
|
86
|
-
|
98
|
+
background-color: #000000;
|
87
99
|
}
|
88
100
|
|
89
101
|
.setting_value {
|
90
102
|
width: 300px;
|
91
103
|
color: #796fe9;
|
92
|
-
|
104
|
+
background-color: #000000;
|
93
105
|
}
|
94
106
|
|
95
107
|
.setting_checkbox {
|
96
108
|
color: #796fe9;
|
97
|
-
|
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:
|
15
|
-
<link rel="stylesheet" href="http://localhost:
|
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>
|
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="
|
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="
|
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="
|
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="
|
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
|
data/lib/template/js/main.js
CHANGED
@@ -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:
|
16
|
-
, height:
|
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:
|
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:
|
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() -
|
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() -
|
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"
|
data/lib/template/start.rb
CHANGED
@@ -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
|
-
|
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
|
data/lib/template/wsserver.rb
CHANGED
@@ -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
|
-
|
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.
|
24
|
-
|
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
|
-
|
63
|
+
ws_send(out)
|
38
64
|
end
|
39
|
-
|
65
|
+
ws_send("app_end:normal")
|
40
66
|
rescue
|
41
67
|
puts $!
|
42
68
|
puts $@
|
43
69
|
puts "app_end:err"
|
44
|
-
|
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
|
-
|
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
|
-
|
88
|
-
|
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
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
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
|
-
|
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.
|
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:
|
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/
|
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
|