python_uml_class 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
data/lib/js/main.js ADDED
@@ -0,0 +1,466 @@
1
+ // main.js
2
+
3
+ var $ws = null;
4
+ var $auto_scroll = true;
5
+ var dialog = null;
6
+ var dialog_timeout = null;
7
+
8
+ function open_dialog(msg, timeout = 0) {
9
+ console.log("msg=" + msg);
10
+ $("#msg_text").html(msg);
11
+ d = $("#msg_dialog").dialog({
12
+ modal: true
13
+ , show: "slide" //表示時のアニメーション
14
+ , hide: "slide" //閉じた時のアニメーション
15
+ , title: "Message" //ダイアログのタイトル
16
+ , width: 500 //ダイアログの横幅
17
+ , height: 300 //ダイアログの高さ
18
+ , resizable: true //リサイズ可
19
+ , closeOnEscape: false //[ESC]キーで閉じられなくする
20
+ , draggable: true //ダイアログの移動を可に
21
+ , buttons: {
22
+ "OK": function () { //Cancelボタン
23
+ if (dialog_timeout != null) {
24
+ clearTimeout(dialog_timeout);
25
+ }
26
+ $(this).dialog("close");
27
+ }
28
+ }
29
+ });
30
+ if (timeout != 0) {
31
+ dialog_timeout = setTimeout(function () {
32
+ d.dialog("close");
33
+ }, timeout);
34
+ }
35
+ }
36
+
37
+ function open_dialog_org(msg) {
38
+ var top = window.screenTop + 10;
39
+ var left = window.screenLeft + 10;
40
+ if (dialog != null) {
41
+ dialog.close();
42
+ }
43
+ var dialog = window.open(
44
+ "/open_dialog?msg=" + msg,
45
+ "pop",
46
+ "width=300, height=100, left=" + left + ", top=" + top
47
+ );
48
+ console.log("open dialog dialog=" + dialog);
49
+ if (dialog == null) {
50
+ console.log("open dialog retry");
51
+ setTimeout(function () {
52
+ open_dialog(msg);
53
+ }, 1000);
54
+ } else {
55
+ dialog.focus();
56
+ }
57
+ }
58
+
59
+ function server_connect(url) {
60
+ var ws = new WebSocket(url);
61
+ ws.onopen = function () {
62
+ // Web Socket is connected. You can send data by send() method.
63
+ ws.send("message to send");
64
+ };
65
+ ws.onmessage = function (evt) {
66
+ //alert(evt.data);
67
+
68
+ if (evt.data.match(/^startup:/)) {
69
+ file_name = evt.data.replace(/^startup:/, "");
70
+ }
71
+ else if (evt.data.match(/^app_start:running/)) {
72
+ open_dialog("処理中です");
73
+ }
74
+ else if (evt.data.match(/^app_end:normal/)) {
75
+ open_dialog("終了しました");
76
+ }
77
+ else if (evt.data.match(/^app_end:stop/)) {
78
+ open_dialog("中止しました");
79
+ }
80
+ else if (evt.data.match(/^app_end:error/)) {
81
+ open_dialog("<font color='red'>エラーが発生しました</font>");
82
+ }
83
+ else if (evt.data.match(/^popup:/)) {
84
+ open_dialog(evt.data.replace(/^popup:/, ""), 3000);
85
+ } else {
86
+ var log = "<li>" + evt.data + "</li>";
87
+ $('#log').append(log);
88
+ if ($auto_scroll) {
89
+ $('.outarea').scrollTop($('.outarea').get(0).scrollHeight);
90
+ }
91
+ }
92
+ };
93
+ ws.onclose = function () {
94
+ alert("アプリケーションが終了しました!!");
95
+ $(window).unbind("beforeunload");
96
+ //window.open('about:blank','_self').close();
97
+ window.close();
98
+ };
99
+ $ws = ws;
100
+ }
101
+
102
+ function send_message(msg) {
103
+ if ($ws != null) {
104
+ $ws.send(msg);
105
+ }
106
+ }
107
+
108
+ function autocomp(id, file_kind) {
109
+ $("#" + id).autocomplete({
110
+ autoFocus: true,
111
+ minLength: 0,
112
+ delay: 0,
113
+ select: function (event, ui) {
114
+ //console.log(ui.item.value);
115
+ jQuery("#" + id).val(ui.item.value);
116
+ //jQuery(this).autocomplete("search", "");
117
+ $(this).keydown();
118
+ },
119
+ source: function (req, resp) {
120
+ $.ajax({
121
+ url: "search?path=" + $("#" + id).val() + "&kind=" + file_kind,
122
+ type: "GET",
123
+ cache: false,
124
+ dataType: "json",
125
+ data: {
126
+ param1: req.term
127
+ },
128
+ success: function (o) {
129
+ resp(o);
130
+ },
131
+ error: function (xhr, ts, err) {
132
+ resp(['']);
133
+ }
134
+ });
135
+
136
+ }
137
+ }).focus(function () {
138
+ //jQuery(this).autocomplete("search", "");
139
+ $(this).keydown();
140
+ });
141
+ }
142
+
143
+ function autocomp_history(id, file_name) {
144
+ $("#" + id).autocomplete({
145
+ autoFocus: true,
146
+ minLength: 0,
147
+ delay: 0,
148
+ select: function (event, ui) {
149
+ jQuery("#" + id).val(ui.item.value);
150
+ $(this).keydown();
151
+ },
152
+ source: function (req, resp) {
153
+ $.ajax({
154
+ url: "history/" + file_name,
155
+ type: "POST",
156
+ cache: false,
157
+ dataType: "json",
158
+ data: {
159
+ param1: req.term
160
+ },
161
+ success: function (o) {
162
+ resp(o);
163
+ },
164
+ error: function (xhr, ts, err) {
165
+ resp(['']);
166
+ }
167
+ });
168
+
169
+ }
170
+ }).focus(function () {
171
+ $(this).keydown();
172
+ });
173
+ }
174
+
175
+ function select_file_dialog(search_id, file_kind, dialog_id, select_file, file_name) {
176
+ $("#" + select_file).click(function () {
177
+ autocomp(search_id, file_kind);
178
+ $(".ui-autocomplete").css("z-index", 1000);
179
+ console.log("name=" + $("#" + file_name).val());
180
+ $("#" + search_id).val($("#" + file_name).val());
181
+ $("#" + dialog_id).dialog({
182
+ modal: true
183
+ , show: "slide" //表示時のアニメーション
184
+ , hide: "explode" //閉じた時のアニメーション
185
+ , title: "Select File" //ダイアログのタイトル
186
+ , width: 580 //ダイアログの横幅
187
+ , height: 400 //ダイアログの高さ
188
+ , resizable: true //リサイズ可
189
+ , closeOnEscape: false //[ESC]キーで閉じられなくする
190
+ , draggable: true //ダイアログの移動を可に
191
+ , buttons: {
192
+ "OK": function () { //OKボタン
193
+ $("#" + file_name).val($("#" + search_id).val());
194
+ $(this).dialog("close");
195
+ $("#" + search_id).autocomplete("destroy");
196
+ },
197
+ "Cancel": function () { //Cancelボタン
198
+ $(this).dialog("close");
199
+ $("#" + search_id).autocomplete("destroy");
200
+ }
201
+ }
202
+ });
203
+ });
204
+ }
205
+
206
+ function setting_dialog(open_id, dialog_id, json_file) {
207
+ var version;
208
+ $("#" + open_id).click(function () {
209
+ $("#" + dialog_id).val = $(function () {
210
+ $("dl#wrap").empty();
211
+ $.getJSON(json_file, function (s) {
212
+ version = s["version"];
213
+ for (var i in s["setting_list"]) {
214
+ if (s["setting_list"][i].type == "input") {
215
+ var h = "<table><tr>"
216
+ + "<td class='setting_name'>" + s["setting_list"][i].description + "</td>"
217
+ + "<td><input class='setting_value' type='text' " + "id=" + s["setting_list"][i].name + "_value " + "value=" + "'" + s["setting_list"][i].value + "'" + ">"
218
+ + "</td></tr></table>"
219
+ $("dl#wrap").append(h);
220
+ } else if (s["setting_list"][i].type == "checkbox") {
221
+ var h = "<table><tr>";
222
+ h += "<td class='setting_name'>" + s["setting_list"][i].description + "</td>";
223
+ if (s["setting_list"][i].value == true) {
224
+ h += "<td><input class='setting_checkbox' type='checkbox' " + "id=" + s["setting_list"][i].name + "_value checked ></td>";
225
+ } else {
226
+ h += "<td><input class='setting_checkbox' type='checkbox' " + "id=" + s["setting_list"][i].name + "_value ></td>";
227
+ }
228
+ h += "</tr></table>";
229
+ $("dl#wrap").append(h);
230
+ } else if (s["setting_list"][i].type == "select") {
231
+ var h = "<table><tr>";
232
+ h += "<td class='setting_name'>" + s["setting_list"][i].description + "</td>";
233
+ h += "<td> <select class='setting_value' id=" + s["setting_list"][i].name + "_value " + ">";
234
+ s["setting_list"][i].select.forEach(e => {
235
+ if (e == s["setting_list"][i].value) {
236
+ h += "<option value=" + e + " selected >" + e + "</option>";
237
+ } else {
238
+ h += "<option value=" + e + ">" + e + "</option>";
239
+ }
240
+ });
241
+ h += "</select></td>";
242
+ h += "</tr></table>";
243
+ $("dl#wrap").append(h);
244
+ } else {
245
+ //console.log("type=" + s["setting_list"][i].type);
246
+ }
247
+ }
248
+ });
249
+ });
250
+ $("#" + dialog_id).dialog({
251
+ modal: true
252
+ , show: "slide" //表示時のアニメーション
253
+ , hide: "explode" //閉じた時のアニメーション
254
+ , title: "Setting" //ダイアログのタイトル
255
+ , width: 580 //ダイアログの横幅
256
+ , height: 400 //ダイアログの高さ
257
+ , resizable: true //リサイズ可
258
+ , closeOnEscape: false //[ESC]キーで閉じられなくする
259
+ , draggable: true //ダイアログの移動を可に
260
+ , buttons: {
261
+ "OK": function () { //OKボタン
262
+ var json_obj = {};
263
+ var json_data = [];
264
+ $.getJSON(json_file, function (s) {
265
+ json_obj["version"] = s["version"];
266
+ for (var i in s["setting_list"]) {
267
+ //console.log(s["setting_list"][i].name);
268
+ if (s["setting_list"][i].type == "input") {
269
+ var data = {};
270
+ data["name"] = s["setting_list"][i].name;
271
+ data["value"] = $("#" + s["setting_list"][i].name + "_value").val();
272
+ data["type"] = s["setting_list"][i].type;
273
+ data["select"] = s["setting_list"][i].select;
274
+ data["description"] = s["setting_list"][i].description;
275
+ json_data.push(data);
276
+ }
277
+ else if (s["setting_list"][i].type == "checkbox") {
278
+ var data = {};
279
+ data["name"] = s["setting_list"][i].name;
280
+ if ($("#" + s["setting_list"][i].name + "_value:checked").val() == "on") {
281
+ data["value"] = true;
282
+ } else {
283
+ data["value"] = false;
284
+ }
285
+ data["type"] = s["setting_list"][i].type;
286
+ data["select"] = s["setting_list"][i].select;
287
+ data["description"] = s["setting_list"][i].description;
288
+ json_data.push(data);
289
+ } else if (s["setting_list"][i].type == "select") {
290
+ var data = {};
291
+ data["name"] = s["setting_list"][i].name;
292
+ data["value"] = $("#" + s["setting_list"][i].name + "_value" + " option:selected").val();
293
+ data["type"] = s["setting_list"][i].type;
294
+ data["select"] = s["setting_list"][i].select;
295
+ data["description"] = s["setting_list"][i].description;
296
+ json_data.push(data);
297
+ } else {
298
+ //console.log("type=" + s["setting_list"][i].type);
299
+ }
300
+ }
301
+ // Jsonデータをサーバに送信
302
+ json_obj["setting_list"] = json_data;
303
+ $ws.send("setting:" + JSON.stringify(json_obj));
304
+ });
305
+ $(this).dialog("close");
306
+ },
307
+ "Cancel": function () { //Cancelボタン
308
+ $(this).dialog("close");
309
+ }
310
+ }
311
+ });
312
+ });
313
+ }
314
+
315
+ // 設定読み込み
316
+ function load_setting(open_id) {
317
+ document.getElementById(open_id).onclick = async () => {
318
+ [fileHandle] = await window.showOpenFilePicker();
319
+ const file = await fileHandle.getFile();
320
+ const json_data = await file.text();
321
+ console.log(json_data);
322
+ // Jsonデータをサーバに送信
323
+ $ws.send("setting:" + json_data);
324
+ };
325
+ }
326
+
327
+ // 設定保存
328
+ function save_setting(open_id, json_file) {
329
+ document.getElementById(open_id).onclick = async () => {
330
+ var json_data = ""
331
+ $.ajax({
332
+ // jsonの読み込み
333
+ type: "GET",
334
+ url: json_file, // ファイルパス(相対パス)
335
+ dataType: "json", // ファイル形式
336
+ async: false // 非同期通信フラグ
337
+ }).then(
338
+ function (json) {
339
+ // 読み込み成功時の処理
340
+ json_data = JSON.stringify(json, null, 2);
341
+ console.log("json=" + json_data);
342
+ },
343
+ function () {
344
+ // 読み込み失敗時の処理
345
+ console.log("読み込みに失敗しました");
346
+ }
347
+ );
348
+ // Jsonを保存
349
+ const opts = {
350
+ suggestedName: 'setting.json',
351
+ types: [{
352
+ description: 'Text file',
353
+ accept: { 'text/plain': ['.json'] },
354
+ }],
355
+ };
356
+ // ファイルをどこにどんな名前で保存するか訊くダイアログを表示
357
+ const saveHandle = await window.showSaveFilePicker(opts)
358
+ // 保存先ファイルに書き込み準備
359
+ const writable = await saveHandle.createWritable();
360
+ // 先程同様に書き込んで終了
361
+ await writable.write(json_data);
362
+ await writable.close();
363
+ };
364
+ }
365
+
366
+ function get_dirname(path) {
367
+ var result = path.replace(/\\/g, '/').replace(/\/[^\/]*$/, '');
368
+ if (result.match(/^[^\/]*\.[^\/\.]*$/)) {
369
+ result = '';
370
+ }
371
+ return result.replace(/\//g, "\\");
372
+ }
373
+
374
+ function dispFile() {
375
+ var fName = $("#inDir").val();
376
+ alert('選択したファイルの値は' + fName + 'です');
377
+ }
378
+
379
+ function openFile(file) {
380
+ $ws.send("openfile:" + file);
381
+ }
382
+
383
+ // 起動時の処理
384
+ $(document).ready(function () {
385
+
386
+ // サーバに接続
387
+ server_connect("ws://localhost:43883/wsserver")
388
+ window.onload = function (e) {
389
+ // サーバに接続
390
+ //server_connect("ws://localhost:43883/wsserver")
391
+ }
392
+
393
+ // menu
394
+ $(function () {
395
+ $(".menu li").hover(
396
+ function () {
397
+ //クラス名「open」を付与する
398
+ $(this).children(".menuSub").addClass("open");
399
+ //hoverが外れた場合
400
+ }, function () {
401
+ //クラス名「open」を取り除く
402
+ $(this).children(".menuSub").removeClass("open");
403
+ }
404
+ );
405
+ });
406
+
407
+ // ウインドウサイズ
408
+ var width = 800;
409
+ var height = 600;
410
+ $(window).resize(function () {
411
+ $(".outarea").height($(window).height() - 180);
412
+ });
413
+ // ウインドウの位置
414
+ $(function () {
415
+ //window.resizeTo(width, height);
416
+ //window.moveTo((window.screen.width / 2) - (width / 2), (screen.height / 2) - (height / 2));
417
+ //window.moveTo(0,0);
418
+ $(".outarea").height($(window).height() - 180);
419
+ });
420
+
421
+ $('.outarea').scroll(function () {
422
+ var h = $('.outarea').get(0).scrollHeight - $('.outarea').innerHeight();
423
+ //console.log("scrollEnd=" + Math.abs($('.outarea').scrollTop() - h));
424
+ if (Math.abs($('.outarea').scrollTop() - h) < 30) {
425
+ // 最後までスクロールしている
426
+ // 自動スクロールON
427
+ $auto_scroll = true;
428
+ } else {
429
+ // 自動スクロールOFF
430
+ $auto_scroll = false;
431
+ }
432
+ //console.log("auto_scroll=" + $auto_scroll);
433
+ });
434
+
435
+ // 設定ダイアログ
436
+ setting_dialog("setting", "setting_dialog", "config/setting.json");
437
+
438
+ // 設定保存
439
+ save_setting("save_setting", "config/setting.json");
440
+
441
+ // 設定読み込み
442
+ load_setting("load_setting");
443
+
444
+ // ハンドラ登録
445
+ $("#stop").click(function () {
446
+ send_message("stop");
447
+ });
448
+
449
+ $("#exec").click(function () {
450
+ $('#log').empty();
451
+ send_message("exec:" + $("#inDir").val() + "," + $("#outFile").val());
452
+ });
453
+
454
+ $("#open_file").click(function () {
455
+ openFile($("#outFile").val());
456
+ });
457
+
458
+ select_file_dialog("search_str", "dir", "dialog1", "select_dir", "inDir");
459
+
460
+ select_file_dialog("search_str2", "file", "dialog2", "select_file", "outFile");
461
+
462
+ autocomp_history("inDir", "history.json")
463
+ autocomp_history("outFile", "out_history.json")
464
+
465
+ });
466
+
@@ -0,0 +1,36 @@
1
+ # -*- coding: utf-8 -*-
2
+ require "server_app_base.rb"
3
+
4
+ class MyApp < AppMainBase
5
+ def start(argv)
6
+ super
7
+ begin
8
+ @abort = false
9
+ puts argv
10
+ argv.each do |v|
11
+ yield v if block_given?
12
+ end
13
+
14
+ # Browserにメッセージ送信
15
+ app_send("popup:start app #{argv[0]}")
16
+
17
+ # 履歴の保存
18
+ add_history("history.json", argv[0])
19
+
20
+ while true
21
+ yield Time.now.to_s if block_given?
22
+ puts Time.now.to_s
23
+ yield @config["name1"]
24
+ sleep 1
25
+ break if @abort
26
+ end
27
+ rescue
28
+ puts $!
29
+ puts $@
30
+ end
31
+ end
32
+
33
+ def stop()
34
+ super
35
+ end
36
+ end
@@ -0,0 +1,5 @@
1
+ # frozen_string_literal: true
2
+
3
+ module PythonUmlClassVer
4
+ VERSION = "0.1.0"
5
+ end
@@ -0,0 +1,55 @@
1
+ # -*- coding: utf-8 -*-
2
+ require "server_app_base.rb"
3
+ require "kconv"
4
+ #require "create_uml_class.rb"
5
+
6
+ class PythonUmlClass < AppMainBase
7
+ def start(argv)
8
+ super
9
+ begin
10
+ @abort = false
11
+ puts argv
12
+ in_dir = argv[0]
13
+ out_file = argv[1]
14
+
15
+ # 履歴の保存
16
+ add_history("history.json", in_dir)
17
+ add_history("out_history.json", out_file)
18
+
19
+ # Browserにメッセージ送信
20
+ #app_send("popup:start app #{argv[0]}")
21
+
22
+ out_svg = out_file.gsub(File.extname(out_file), "") + ".svg"
23
+
24
+ # uml作成
25
+ load "create_uml_class.rb"
26
+
27
+ uml = create_uml_class(in_dir, out_file)
28
+
29
+ File.open(out_file, "w") do |f|
30
+ f.puts uml
31
+ end
32
+
33
+ # PlantUMLの実行
34
+ FileUtils.rm_f out_svg
35
+ cmd = "#{@config["plantuml"]} #{out_file}"
36
+ puts cmd
37
+ system cmd
38
+ if File.exist? out_svg
39
+ yield File.read out_svg
40
+ else
41
+ yield "exec error"
42
+ yield cmd
43
+ end
44
+ rescue
45
+ puts $!
46
+ puts $@
47
+ yield $!.to_s.toutf8
48
+ yield $@.to_s.toutf8
49
+ end
50
+ end
51
+
52
+ def stop()
53
+ super
54
+ end
55
+ end
data/lib/server.rb ADDED
@@ -0,0 +1,58 @@
1
+ require "json"
2
+ require "kconv"
3
+
4
+ class Search < Sinatra::Base
5
+ helpers Sinatra::Streaming
6
+ get "" do
7
+ q_hash = {}
8
+ puts request.query_string
9
+ request.query_string.split("&").each do |q|
10
+ work = q.split("=")
11
+ if work[1] != nil
12
+ q_hash[work[0]] = CGI.unescape work[1].toutf8
13
+ else
14
+ q_hash[work[0]] = ""
15
+ end
16
+ end
17
+ str = q_hash["path"].gsub(/\\/, "/")
18
+ puts "str=#{str}"
19
+ kind = q_hash["kind"].gsub(/\\/, "/")
20
+ puts "kind=#{kind}"
21
+ res = []
22
+ str = str.gsub(/\\/, "/")
23
+ dir = File.dirname(str)
24
+ file = File.basename(str)
25
+ puts "dir=#{dir}"
26
+ puts "file=#{file}"
27
+
28
+ kernel = Facter.value(:kernel)
29
+ if kernel == "windows"
30
+ dir = "c:/" if dir == nil
31
+ dir = "c:/" if dir == "/"
32
+ elsif kernel == "Linux"
33
+ dir = "/" if dir == nil
34
+ else
35
+ dir = "c:/" if dir == nil
36
+ dir = "c:/" if dir == "/"
37
+ end
38
+
39
+ path = "#{dir}/#{file}"
40
+ if File.directory?(path)
41
+ path = path + "/*"
42
+ else
43
+ path = path + "*"
44
+ end
45
+ path.gsub!(/[\/]+/, "/")
46
+ puts path
47
+ Dir.glob(path, File::FNM_DOTMATCH).each do |file|
48
+ data = {}
49
+ next if File.basename(file) == "."
50
+ next if kind == "dir" and !File.directory?(file)
51
+ data["label"] = File.basename(file)
52
+ data["label"] += "/" if (File.directory?(file))
53
+ data["value"] = File.expand_path(file)
54
+ res.push data
55
+ end
56
+ JSON.generate res.sort { |a, b| a["value"] <=> b["value"] }
57
+ end
58
+ end
@@ -0,0 +1,63 @@
1
+ # -*- coding: utf-8 -*-
2
+ class AppMainBase
3
+ def initialize
4
+ @config = nil
5
+ @aboet = false
6
+ @exec = false
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
19
+ end
20
+
21
+ def set_config(config)
22
+ @config = config
23
+ end
24
+
25
+ def start(argv)
26
+ @exec = true
27
+ end
28
+
29
+ def stop()
30
+ @abort = true
31
+ @exec = false
32
+ end
33
+
34
+ def suspend()
35
+ @suspend = true
36
+ end
37
+
38
+ def resume()
39
+ @suspend = false
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
61
+ end
62
+
63
+ require "app_load.rb"