erd_map 0.1.3 → 0.1.5

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: 860c0712604342f0e495b6ff55da67a041d7b886bfc7e561aa96c0bf848a3290
4
- data.tar.gz: 89d513411e0732f0583c1613d7ebb961519f0d1248166204289d0c30419578b2
3
+ metadata.gz: ff2d016ce1d70f303ba81a480185f13058d35cb1f0cd98c224637eaadaac481b
4
+ data.tar.gz: a48d58de84ed40da26d8327aac5fb2241c51ddf1333eca9365398ce72fb79628
5
5
  SHA512:
6
- metadata.gz: eba427423e7d20c9246b45a7e87a4785da9ebe38a91c303bcbbfe5203013ab47808aa651857f631383cf46414a21319f294e4c2dbd700379451e49b2107595e0
7
- data.tar.gz: 26700b51e97658e85f0cab1f3c4056c50836d4d1a3d60f1cbc4b15ca2e8f4604e25c882d9a91dc5ead1295cca7dc16734fc41316ad7a3395104b4420f67f1acd
6
+ metadata.gz: 0aad4e151277b66e1996d5953552de91f9798e2e566f5b01869cad123c6c7e83cd69f35960cc6741ecda719d77da118b172e63e1b2efc168512663e23153752c
7
+ data.tar.gz: bdf8341667f56d3ed3ed20a9c3204a485b078a81ee2288942c83e9b6821e22e4e4db989afdbaf677de8529c19e3a0a895930bc3e3c7aac8cd7a4c48486687275
data/README.md CHANGED
@@ -37,6 +37,8 @@ pyenv global $(pyenv install --list | grep -E '^\s*[0-9]+\.[0-9]+\.[0-9]+$' | ta
37
37
  ```bash
38
38
  # Install packages, for example with pip
39
39
  pip install networkx bokeh scipy
40
+ # with pip3
41
+ pip3 install networkx bokeh scipy
40
42
  ```
41
43
 
42
44
  ## Installation
@@ -59,7 +61,7 @@ Add the following to your `config/routes.rb` and access `/erd_map` in your brows
59
61
 
60
62
  ```ruby
61
63
  Rails.application.routes.draw do
62
- mount ErdMap::Engine => "erd_map"
64
+ mount ErdMap::Engine => "erd_map" if defined?(ErdMap)
63
65
  end
64
66
  ```
65
67
 
@@ -2,30 +2,22 @@
2
2
 
3
3
  module ErdMap
4
4
  class ErdMapController < ApplicationController
5
- FILE_PATH = Rails.root.join("tmp", "erd_map", "map.html")
6
-
7
5
  skip_forgery_protection
8
6
 
9
7
  def index
10
- if File.exist?(FILE_PATH)
11
- render html: File.read(FILE_PATH).html_safe
8
+ if File.exist?(ErdMap::MAP_FILE)
9
+ render html: File.read(ErdMap::MAP_FILE).html_safe
12
10
  else
13
- _stdout, stderr, status = Open3.capture3("rails runner 'ErdMap::MapBuilder.build'")
14
- if status.success?
15
- render html: File.read(FILE_PATH).html_safe
16
- else
17
- render plain: "Error: #{stderr}", status: :unprocessable_entity
18
- end
11
+ pid = spawn("rails erd_map")
12
+ Process.detach(pid)
19
13
  end
20
14
  end
21
15
 
22
16
  def update
23
- _stdout, stderr, status = Open3.capture3("rails runner 'ErdMap::MapBuilder.build'")
24
- if status.success?
25
- head :ok
26
- else
27
- render json: { message: "Error: \n#{stderr}" }, status: :unprocessable_entity
28
- end
17
+ File.delete(ErdMap::MAP_FILE) if File.exist?(ErdMap::MAP_FILE)
18
+ pid = spawn("rails erd_map")
19
+ Process.detach(pid)
20
+ redirect_to erd_map.root_path, status: :see_other
29
21
  end
30
22
  end
31
23
  end
@@ -0,0 +1,7 @@
1
+ <script>
2
+ document.addEventListener("DOMContentLoaded", () => {
3
+ setInterval(() => { window.location.reload() }, 5000)
4
+ })
5
+ </script>
6
+
7
+ Computing...
@@ -1,3 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- ErdMap.py_call_modules = ErdMap::PyCallModules.new
3
+ module ErdMap
4
+ TMP_DIR = Rails.root.join("tmp", "erd_map")
5
+ LOCK_FILE = Rails.root.join("tmp", "erd_map", "task.pid")
6
+ MAP_FILE = Rails.root.join("tmp", "erd_map", "map.html")
7
+ end
data/lib/erd_map/graph.rb CHANGED
@@ -99,6 +99,15 @@ module ErdMap
99
99
  end
100
100
  end
101
101
 
102
+ def nodes_with_i18n_labels
103
+ return @nodes_with_i18n_labels if @nodes_with_i18n_labels
104
+ @nodes_with_i18n_labels = {}
105
+ whole_models.each do |model|
106
+ @nodes_with_i18n_labels[model.name] = model.model_name.human(default: "")
107
+ end
108
+ @nodes_with_i18n_labels
109
+ end
110
+
102
111
  def association_columns
103
112
  return @association_columns if @association_columns
104
113
 
@@ -42,11 +42,11 @@ module ErdMap
42
42
  layoutsByChunkData: graph.layouts_by_chunk.to_json,
43
43
  chunkedNodesData: graph.chunked_nodes.to_json,
44
44
  nodeWithCommunityIndexData: graph.node_with_community_index.to_json,
45
- searchBox: plot.button_set[:search_box],
46
- selectingNodeLabel: plot.button_set[:selecting_node_label],
47
- zoomModeToggle: plot.button_set[:zoom_mode_toggle],
48
- tapModeToggle: plot.button_set[:tap_mode_toggle],
49
- displayTitleModeToggle: plot.button_set[:display_title_mode_toggle],
45
+ searchBox: plot.search_box,
46
+ selectingNodeLabel: plot.selecting_node_label,
47
+ zoomModeToggle: plot.zoom_mode_toggle,
48
+ tapModeToggle: plot.tap_mode_toggle,
49
+ displayTitleModeToggle: plot.display_title_mode_toggle,
50
50
  nodeLabels: {
51
51
  titleModelLabel: title_model_label,
52
52
  foreignModelLabel: foreign_model_label,
@@ -81,12 +81,14 @@ module ErdMap
81
81
 
82
82
  columns_label = []
83
83
  title_label = []
84
+ i18n_label = []
84
85
  rect_heights = []
85
86
  graph.node_names.map do |node_name|
86
87
  title_text = format_text([node_name], title: true)
87
88
  columns_text = [*title_text.scan("\n"), "\n", format_text(graph.association_columns[node_name])].join
88
89
  columns_label << columns_text
89
90
  title_label << [title_text, "\n", *columns_text.scan("\n")].join
91
+ i18n_label << [node_name, graph.nodes_with_i18n_labels[node_name]].compact_blank.join("\n")
90
92
 
91
93
  padding = 36
92
94
  line_count = columns_text.scan("\n").size + 1
@@ -102,6 +104,7 @@ module ErdMap
102
104
  radius: graph.node_radius,
103
105
  original_radius: graph.node_radius,
104
106
  rect_height: rect_heights,
107
+ i18n_label: i18n_label,
105
108
  title_label: title_label,
106
109
  columns_label: columns_label,
107
110
  fill_color: graph.node_colors,
@@ -181,7 +184,7 @@ module ErdMap
181
184
  bokeh_models.LabelSet.new(
182
185
  x: "x",
183
186
  y: "y",
184
- text: "index",
187
+ text: { field: "i18n_label" },
185
188
  source: graph_renderer.node_renderer.data_source,
186
189
  text_font_size: "12pt",
187
190
  text_color: { field: "text_color" },
@@ -33,19 +33,7 @@ module ErdMap
33
33
  bokeh_models.Column.new(
34
34
  children: [
35
35
  bokeh_models.Row.new(
36
- children: [
37
- plot.button_set[:left_spacer],
38
- plot.button_set[:selecting_node_label],
39
- plot.button_set[:search_box],
40
- plot.button_set[:zoom_mode_toggle],
41
- plot.button_set[:tap_mode_toggle],
42
- plot.button_set[:display_title_mode_toggle],
43
- plot.button_set[:re_layout_button],
44
- plot.button_set[:zoom_in_button],
45
- plot.button_set[:zoom_out_button],
46
- plot.button_set[:re_compute_button],
47
- plot.button_set[:right_spacer],
48
- ],
36
+ children: plot.header,
49
37
  sizing_mode: "stretch_width",
50
38
  ),
51
39
  plot.plot,
@@ -55,13 +43,9 @@ module ErdMap
55
43
  end
56
44
 
57
45
  def save(layout)
58
- tmp_dir = Rails.root.join("tmp", "erd_map")
59
- FileUtils.makedirs(tmp_dir) unless Dir.exist?(tmp_dir)
60
- output_path = File.join(tmp_dir, "map.html")
61
-
62
- bokeh_io.output_file(output_path)
46
+ bokeh_io.output_file(ErdMap::MAP_FILE.to_s)
63
47
  bokeh_io.save(layout)
64
- puts output_path
48
+ puts "[erd_map] #{ErdMap::MAP_FILE} (#{Process.pid})"
65
49
  end
66
50
 
67
51
  def setup_graph_manager(plot)
@@ -106,9 +90,19 @@ module ErdMap
106
90
 
107
91
  class << self
108
92
  def build
109
- Rails.logger.info "build start"
93
+ log "Loading modules starts."
94
+ ErdMap.load_py_call_modules
95
+ log "Loading modules completed."
96
+
97
+ log "Building map starts."
110
98
  new.execute
111
- Rails.logger.info "build completed"
99
+ log "Building map completed."
100
+ end
101
+
102
+ private
103
+
104
+ def log(text)
105
+ puts "[erd_map] #{text} (#{Process.pid})"
112
106
  end
113
107
  end
114
108
  end
data/lib/erd_map/plot.rb CHANGED
@@ -26,8 +26,8 @@ module ErdMap
26
26
  end
27
27
  end
28
28
 
29
- def button_set
30
- @button_set ||= ButtonSet.new
29
+ def header
30
+ @header.to_a
31
31
  end
32
32
 
33
33
  private
@@ -36,6 +36,7 @@ module ErdMap
36
36
 
37
37
  def initialize(graph)
38
38
  @graph = graph
39
+ @header = Header.new
39
40
  register_callback
40
41
  end
41
42
 
@@ -70,14 +71,34 @@ module ErdMap
70
71
  JS
71
72
  end
72
73
 
73
- class ButtonSet
74
+ class Header
74
75
  extend Forwardable
75
- def_delegators :@button_set, :[]
76
+ ACCESSIBLE_PARTS = [:search_box, :selecting_node_label, :zoom_mode_toggle, :tap_mode_toggle, :display_title_mode_toggle]
77
+
78
+ def to_a
79
+ [
80
+ :left_spacer,
81
+ :selecting_node_label,
82
+ :search_box,
83
+ :zoom_mode_toggle,
84
+ :tap_mode_toggle,
85
+ :display_title_mode_toggle,
86
+ :re_layout_button,
87
+ :zoom_in_button,
88
+ :zoom_out_button,
89
+ :re_compute_button,
90
+ :right_spacer,
91
+ ].map { |name| @header[name] }
92
+ end
76
93
 
77
94
  private
78
95
 
96
+ ACCESSIBLE_PARTS.each do |name|
97
+ define_method(name) { @header[name] }
98
+ end
99
+
79
100
  def initialize
80
- @button_set = {
101
+ @header = {
81
102
  left_spacer: left_spacer,
82
103
  selecting_node_label: selecting_node_label,
83
104
  search_box: search_box,
@@ -159,19 +180,17 @@ module ErdMap
159
180
  button.disabled = true
160
181
  button.label = "Computing ..."
161
182
 
162
- fetch("/erd_map", { method: "PUT" })
163
- .then(response => {
164
- if (response.ok) { return response.text() }
165
- else { return response.json().then(json => { throw new Error(json.message) }) }
166
- })
167
- .then(data => { window.location.reload() })
168
- .catch(error => {
169
- alert(error.message)
170
- console.error(error)
171
-
172
- button.disabled = false
173
- button.label = "Re-Compute"
174
- })
183
+ const form = document.createElement("form")
184
+ form.method = "POST"
185
+ form.action = "/erd_map"
186
+ form.style.display = "none"
187
+ const input = document.createElement("input")
188
+ input.type = "hidden"
189
+ input.name = "_method"
190
+ input.value = "PUT"
191
+ form.appendChild(input)
192
+ document.body.appendChild(form)
193
+ form.submit()
175
194
  JS
176
195
  )
177
196
  )
@@ -191,5 +210,9 @@ module ErdMap
191
210
  )
192
211
  end
193
212
  end
213
+
214
+ Header::ACCESSIBLE_PARTS.each do |name|
215
+ public define_method(name) { @header.__send__(name) }
216
+ end
194
217
  end
195
218
  end
@@ -1,3 +1,3 @@
1
1
  module ErdMap
2
- VERSION = "0.1.3"
2
+ VERSION = "0.1.5"
3
3
  end
data/lib/erd_map.rb CHANGED
@@ -12,8 +12,8 @@ module ErdMap
12
12
  @py_call_modules
13
13
  end
14
14
 
15
- def py_call_modules=(py_call_modules)
16
- @py_call_modules = py_call_modules
15
+ def load_py_call_modules
16
+ @py_call_modules = ErdMap::PyCallModules.new
17
17
  end
18
18
  end
19
19
  end
@@ -1,8 +1,27 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  desc "Compute erd_map"
4
- task erd_map: :environment do
5
- puts "Map computing start."
6
- ErdMap::MapBuilder.build
7
- puts "Map computing completed."
4
+ task erd_map: :environment do
5
+ FileUtils.makedirs(ErdMap::TMP_DIR) unless Dir.exist?(ErdMap::TMP_DIR)
6
+ timeout = 5 * 60
7
+
8
+ if File.exist?(ErdMap::LOCK_FILE)
9
+ pid = File.read(ErdMap::LOCK_FILE).to_i
10
+
11
+ if Time.now - File.mtime(ErdMap::LOCK_FILE) > timeout
12
+ puts "[erd_map] Lock expired. Kill process and remove lock file (pid: #{pid}, file: #{ErdMap::LOCK_FILE})."
13
+ Process.kill("KILL", pid) rescue nil
14
+ File.delete(ErdMap::LOCK_FILE)
15
+ else
16
+ puts "[erd_map] ErdMap is already computing (pid: #{pid}, file: #{ErdMap::LOCK_FILE})."
17
+ exit 0
18
+ end
19
+ end
20
+
21
+ File.open(ErdMap::LOCK_FILE, File::WRONLY|File::CREAT|File::TRUNC, 0644) do |f|
22
+ f.write(Process.pid)
23
+ f.flush
24
+ ErdMap::MapBuilder.build
25
+ end
26
+ File.delete(ErdMap::LOCK_FILE)
8
27
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: erd_map
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.3
4
+ version: 0.1.5
5
5
  platform: ruby
6
6
  authors:
7
7
  - makicamel
@@ -68,6 +68,7 @@ files:
68
68
  - app/controllers/erd_map/erd_map_controller.rb
69
69
  - app/helpers/erd_map/application_helper.rb
70
70
  - app/models/erd_map/application_record.rb
71
+ - app/views/erd_map/erd_map/index.html.erb
71
72
  - app/views/layouts/erd_map/application.html.erb
72
73
  - config/initializers/erd_map.rb
73
74
  - config/routes.rb