lucidMachines 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 +7 -0
- data/.gitignore +9 -0
- data/.~lock.integration.csv# +1 -0
- data/CODE_OF_CONDUCT.md +74 -0
- data/Gemfile +4 -0
- data/Gemfile.lock +32 -0
- data/README.md +39 -0
- data/Rakefile +2 -0
- data/aasm_export.rb +380 -0
- data/bin/console +14 -0
- data/bin/setup +8 -0
- data/chart.rb +133 -0
- data/comptes/#comptes.rb# +66 -0
- data/comptes/comptes.rb +64 -0
- data/comptes/comptes.rb~ +56 -0
- data/comptes/credentials.json +1 -0
- data/comptes/token.yaml +2 -0
- data/credentials.json +1 -0
- data/elements.rb +111 -0
- data/exe/lucidMachines +6 -0
- data/exporter.rb +41 -0
- data/graphviz_export.rb +75 -0
- data/integration.csv +213 -0
- data/lib/lucidMachines/aasm_export.rb +376 -0
- data/lib/lucidMachines/chart.rb +132 -0
- data/lib/lucidMachines/cli.rb +68 -0
- data/lib/lucidMachines/elements.rb +107 -0
- data/lib/lucidMachines/exporter.rb +39 -0
- data/lib/lucidMachines/graphviz_export.rb +71 -0
- data/lib/lucidMachines/loader.rb +95 -0
- data/lib/lucidMachines/version.rb +3 -0
- data/lib/lucidMachines.rb +19 -0
- data/loader.rb +99 -0
- data/lucidMachines.gemspec +48 -0
- data/quickstart/quickstart/credentials.json +1 -0
- data/quickstart/quickstart/quickstart.rb +54 -0
- data/quickstart/quickstart/token.yaml +2 -0
- metadata +167 -0
data/chart.rb
ADDED
@@ -0,0 +1,133 @@
|
|
1
|
+
module ChartReader
|
2
|
+
class Chart
|
3
|
+
attr_reader :pages, :blocks, :links
|
4
|
+
|
5
|
+
def initialize
|
6
|
+
@pages = {}
|
7
|
+
@blocks = {}
|
8
|
+
@links = {}
|
9
|
+
end
|
10
|
+
|
11
|
+
def states
|
12
|
+
@blocks.each_value.select{|b| b.is_state?}
|
13
|
+
end
|
14
|
+
|
15
|
+
def states_on_page(page)
|
16
|
+
@blocks.each_value.select{|b| b.is_state? and b.page == page }
|
17
|
+
end
|
18
|
+
|
19
|
+
def blocks_on_page(page)
|
20
|
+
@blocks.each_value.select{|b| b.page == page }
|
21
|
+
end
|
22
|
+
|
23
|
+
def get_blocks_of_type(type)
|
24
|
+
@blocks.each_value.select do |b|
|
25
|
+
b.type.eql? type
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
|
30
|
+
def add_page(page)
|
31
|
+
@pages[page.id] = page
|
32
|
+
end
|
33
|
+
|
34
|
+
def get_page(id)
|
35
|
+
return @pages[id]
|
36
|
+
end
|
37
|
+
|
38
|
+
def page(name_to_find)
|
39
|
+
out = @pages.values.select do |p|
|
40
|
+
p.name.eql? name_to_find
|
41
|
+
end
|
42
|
+
|
43
|
+
return nil if out.empty?
|
44
|
+
return out.first
|
45
|
+
end
|
46
|
+
|
47
|
+
# same for blocks
|
48
|
+
def add_block(b) ; @blocks[b.id] = b; end
|
49
|
+
def get_block(id); @blocks[id] ; end
|
50
|
+
|
51
|
+
# same for links
|
52
|
+
def add_link(l) ; @links[l.id] = l; end
|
53
|
+
def get_link(id); @links[id] ; end
|
54
|
+
|
55
|
+
def has_block?(id)
|
56
|
+
@blocks.has_key? id
|
57
|
+
end
|
58
|
+
|
59
|
+
|
60
|
+
# replace text with objects
|
61
|
+
def set_pages
|
62
|
+
@pages.each_value do |page|
|
63
|
+
@blocks.each_value do |block|
|
64
|
+
page.set_block(block.id, block) if block.page_id == page.id
|
65
|
+
end
|
66
|
+
@links.each_value do |link|
|
67
|
+
link.set_page(page) if link.page_id == page.id
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
# replace text with objects
|
73
|
+
def set_links
|
74
|
+
@links.each_value do |link|
|
75
|
+
source_block = get_block(link.source)
|
76
|
+
destination_block = get_block(link.destination)
|
77
|
+
|
78
|
+
next if source_block.nil? or destination_block.nil?
|
79
|
+
|
80
|
+
source_block.link_to destination_block, link
|
81
|
+
destination_block.link_from source_block, link
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
def check_initial
|
86
|
+
@blocks.each_value do |b|
|
87
|
+
next unless b.has_links?
|
88
|
+
b.links_from.each_value do |b2|
|
89
|
+
if b2.text.eql? "Initial"
|
90
|
+
b2.hide
|
91
|
+
b.set_initial
|
92
|
+
end
|
93
|
+
end
|
94
|
+
end
|
95
|
+
end
|
96
|
+
|
97
|
+
|
98
|
+
def subchart_for_page(page)
|
99
|
+
chart = Chart.new
|
100
|
+
|
101
|
+
# add the page
|
102
|
+
chart.add_page!( { page.id => page} )
|
103
|
+
|
104
|
+
# add the blocks of this page
|
105
|
+
|
106
|
+
@blocks.each do |block_id, block|
|
107
|
+
next unless block.page == page
|
108
|
+
chart.add_block!({ block_id => block })
|
109
|
+
end
|
110
|
+
|
111
|
+
# add the links of this page
|
112
|
+
@links.each do |link_id, link|
|
113
|
+
next unless link.page == page
|
114
|
+
chart.add_link!({ link_id => link })
|
115
|
+
end
|
116
|
+
|
117
|
+
return chart
|
118
|
+
end
|
119
|
+
|
120
|
+
def add_page!(page)
|
121
|
+
@pages.merge!(page)
|
122
|
+
end
|
123
|
+
|
124
|
+
def add_block!(block)
|
125
|
+
@blocks.merge!(block)
|
126
|
+
end
|
127
|
+
|
128
|
+
def add_link!(link)
|
129
|
+
@links.merge!(link)
|
130
|
+
end
|
131
|
+
|
132
|
+
end
|
133
|
+
end
|
@@ -0,0 +1,66 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
require 'google/apis/sheets_v4'
|
3
|
+
require 'googleauth'
|
4
|
+
require 'googleauth/stores/file_token_store'
|
5
|
+
require 'fileutils'
|
6
|
+
|
7
|
+
OOB_URI = 'urn:ietf:wg:oauth:2.0:oob'.freeze
|
8
|
+
APPLICATION_NAME = 'Google Sheets API Ruby Quickstart'.freeze
|
9
|
+
CREDENTIALS_PATH = 'credentials.json'.freeze
|
10
|
+
# The file token.yaml stores the user's access and refresh tokens, and is
|
11
|
+
# created automatically when the authorization flow completes for the first
|
12
|
+
# time.
|
13
|
+
TOKEN_PATH = 'token.yaml'.freeze
|
14
|
+
SCOPE = Google::Apis::SheetsV4::AUTH_SPREADSHEETS
|
15
|
+
|
16
|
+
##
|
17
|
+
# Ensure valid credentials, either by restoring from the saved credentials
|
18
|
+
# files or intitiating an OAuth2 authorization. If authorization is required,
|
19
|
+
# the user's default browser will be launched to approve the request.
|
20
|
+
#
|
21
|
+
# @return [Google::Auth::UserRefreshCredentials] OAuth2 credentials
|
22
|
+
def authorize
|
23
|
+
client_id = Google::Auth::ClientId.from_file(CREDENTIALS_PATH)
|
24
|
+
token_store = Google::Auth::Stores::FileTokenStore.new(file: TOKEN_PATH)
|
25
|
+
authorizer = Google::Auth::UserAuthorizer.new(client_id, SCOPE, token_store)
|
26
|
+
user_id = 'default'
|
27
|
+
credentials = authorizer.get_credentials(user_id)
|
28
|
+
if credentials.nil?
|
29
|
+
url = authorizer.get_authorization_url(base_url: OOB_URI)
|
30
|
+
puts 'Open the following URL in the browser and enter the ' \
|
31
|
+
"resulting code after authorization:\n" + url
|
32
|
+
code = gets
|
33
|
+
credentials = authorizer.get_and_store_credentials_from_code(
|
34
|
+
user_id: user_id, code: code, base_url: OOB_URI
|
35
|
+
)
|
36
|
+
end
|
37
|
+
credentials
|
38
|
+
end
|
39
|
+
|
40
|
+
# Initialize the API
|
41
|
+
service = Google::Apis::SheetsV4::SheetsService.new
|
42
|
+
service.client_options.application_name = APPLICATION_NAME
|
43
|
+
service.authorization = authorize
|
44
|
+
|
45
|
+
# Prints the names and majors of students in a sample spreadsheet:
|
46
|
+
# https://docs.google.com/spreadsheets/d/1BxiMVs0XRA5nFMdKvBdBZjgmUUqptlbs74OgvE2upms/edit
|
47
|
+
spreadsheet_id = '1YfsXVfFfPHjsry7zBwplFIP4T1ZwAgswZhG4EPWriqM'
|
48
|
+
range = 'Dépenses mensuelles!B8:E15'
|
49
|
+
|
50
|
+
response = service.get_spreadsheet_values(spreadsheet_id, range)
|
51
|
+
puts 'Name, Major:'
|
52
|
+
puts 'No data found.' if response.values.empty?
|
53
|
+
response.values.each do |row|
|
54
|
+
# Print columns A and E, which correspond to indices 0 and 4.
|
55
|
+
puts "#{row[1]}, #{row[4]}"
|
56
|
+
end
|
57
|
+
|
58
|
+
|
59
|
+
spreadsheet = service.get_spreadsheet(spreadsheet_id)
|
60
|
+
|
61
|
+
range2 = 'Dépenses mensuelles!B16:E17'
|
62
|
+
request_body = Google::Apis::SheetsV4::ValueRange.new
|
63
|
+
|
64
|
+
request_body.values = [["Hello", "Yo"], ["Haa", "Hey"]]
|
65
|
+
value_input_option = 'raw' # TODO: Update placeholder value.
|
66
|
+
service.append_spreadsheet_value(spreadsheet_id, range, request_body, value_input_option: value_input_option)
|
data/comptes/comptes.rb
ADDED
@@ -0,0 +1,64 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
require 'google/apis/sheets_v4'
|
3
|
+
require 'googleauth'
|
4
|
+
require 'googleauth/stores/file_token_store'
|
5
|
+
require 'fileutils'
|
6
|
+
|
7
|
+
OOB_URI = 'urn:ietf:wg:oauth:2.0:oob'.freeze
|
8
|
+
APPLICATION_NAME = 'Google Sheets API Ruby Quickstart'.freeze
|
9
|
+
CREDENTIALS_PATH = 'credentials.json'.freeze
|
10
|
+
# The file token.yaml stores the user's access and refresh tokens, and is
|
11
|
+
# created automatically when the authorization flow completes for the first
|
12
|
+
# time.
|
13
|
+
TOKEN_PATH = 'token.yaml'.freeze
|
14
|
+
SCOPE = Google::Apis::SheetsV4::AUTH_SPREADSHEETS
|
15
|
+
|
16
|
+
##
|
17
|
+
# Ensure valid credentials, either by restoring from the saved credentials
|
18
|
+
# files or intitiating an OAuth2 authorization. If authorization is required,
|
19
|
+
# the user's default browser will be launched to approve the request.
|
20
|
+
#
|
21
|
+
# @return [Google::Auth::UserRefreshCredentials] OAuth2 credentials
|
22
|
+
def authorize
|
23
|
+
client_id = Google::Auth::ClientId.from_file(CREDENTIALS_PATH)
|
24
|
+
token_store = Google::Auth::Stores::FileTokenStore.new(file: TOKEN_PATH)
|
25
|
+
authorizer = Google::Auth::UserAuthorizer.new(client_id, SCOPE, token_store)
|
26
|
+
user_id = 'default'
|
27
|
+
credentials = authorizer.get_credentials(user_id)
|
28
|
+
if credentials.nil?
|
29
|
+
url = authorizer.get_authorization_url(base_url: OOB_URI)
|
30
|
+
puts 'Open the following URL in the browser and enter the ' \
|
31
|
+
"resulting code after authorization:\n" + url
|
32
|
+
code = gets
|
33
|
+
credentials = authorizer.get_and_store_credentials_from_code(
|
34
|
+
user_id: user_id, code: code, base_url: OOB_URI
|
35
|
+
)
|
36
|
+
end
|
37
|
+
credentials
|
38
|
+
end
|
39
|
+
|
40
|
+
# Initialize the API
|
41
|
+
service = Google::Apis::SheetsV4::SheetsService.new
|
42
|
+
service.client_options.application_name = APPLICATION_NAME
|
43
|
+
service.authorization = authorize
|
44
|
+
|
45
|
+
# Prints the names and majors of students in a sample spreadsheet:
|
46
|
+
# https://docs.google.com/spreadsheets/d/1BxiMVs0XRA5nFMdKvBdBZjgmUUqptlbs74OgvE2upms/edit
|
47
|
+
spreadsheet_id = '1YfsXVfFfPHjsry7zBwplFIP4T1ZwAgswZhG4EPWriqM'
|
48
|
+
range = 'Dépenses mensuelles!B8:E15'
|
49
|
+
|
50
|
+
response = service.get_spreadsheet_values(spreadsheet_id, range)
|
51
|
+
puts 'Name, Major:'
|
52
|
+
puts 'No data found.' if response.values.empty?
|
53
|
+
response.values.each do |row|
|
54
|
+
# Print columns A and E, which correspond to indices 0 and 4.
|
55
|
+
puts "#{row[1]}, #{row[4]}"
|
56
|
+
end
|
57
|
+
|
58
|
+
|
59
|
+
range2 = 'Dépenses mensuelles!B16:E17'
|
60
|
+
request_body = Google::Apis::SheetsV4::ValueRange.new
|
61
|
+
|
62
|
+
request_body.values = [["Hello", "Yo"], ["Haa", "Hey"]]
|
63
|
+
value_input_option = 'raw' # TODO: Update placeholder value.
|
64
|
+
service.append_spreadsheet_value(spreadsheet_id, range, request_body, value_input_option: value_input_option)
|
data/comptes/comptes.rb~
ADDED
@@ -0,0 +1,56 @@
|
|
1
|
+
require 'google/apis/sheets_v4'
|
2
|
+
require 'googleauth'
|
3
|
+
require 'googleauth/stores/file_token_store'
|
4
|
+
require 'fileutils'
|
5
|
+
|
6
|
+
OOB_URI = 'urn:ietf:wg:oauth:2.0:oob'.freeze
|
7
|
+
APPLICATION_NAME = 'Google Sheets API Ruby Quickstart'.freeze
|
8
|
+
CREDENTIALS_PATH = 'credentials.json'.freeze
|
9
|
+
# The file token.yaml stores the user's access and refresh tokens, and is
|
10
|
+
# created automatically when the authorization flow completes for the first
|
11
|
+
# time.
|
12
|
+
TOKEN_PATH = 'token.yaml'.freeze
|
13
|
+
SCOPE = Google::Apis::SheetsV4::AUTH_SPREADSHEETS_READONLY
|
14
|
+
|
15
|
+
##
|
16
|
+
# Ensure valid credentials, either by restoring from the saved credentials
|
17
|
+
# files or intitiating an OAuth2 authorization. If authorization is required,
|
18
|
+
# the user's default browser will be launched to approve the request.
|
19
|
+
#
|
20
|
+
# @return [Google::Auth::UserRefreshCredentials] OAuth2 credentials
|
21
|
+
def authorize
|
22
|
+
client_id = Google::Auth::ClientId.from_file(CREDENTIALS_PATH)
|
23
|
+
token_store = Google::Auth::Stores::FileTokenStore.new(file: TOKEN_PATH)
|
24
|
+
authorizer = Google::Auth::UserAuthorizer.new(client_id, SCOPE, token_store)
|
25
|
+
user_id = 'default'
|
26
|
+
credentials = authorizer.get_credentials(user_id)
|
27
|
+
if credentials.nil?
|
28
|
+
url = authorizer.get_authorization_url(base_url: OOB_URI)
|
29
|
+
puts 'Open the following URL in the browser and enter the ' \
|
30
|
+
"resulting code after authorization:\n" + url
|
31
|
+
code = gets
|
32
|
+
credentials = authorizer.get_and_store_credentials_from_code(
|
33
|
+
user_id: user_id, code: code, base_url: OOB_URI
|
34
|
+
)
|
35
|
+
end
|
36
|
+
credentials
|
37
|
+
end
|
38
|
+
|
39
|
+
# Initialize the API
|
40
|
+
service = Google::Apis::SheetsV4::SheetsService.new
|
41
|
+
service.client_options.application_name = APPLICATION_NAME
|
42
|
+
service.authorization = authorize
|
43
|
+
|
44
|
+
# Prints the names and majors of students in a sample spreadsheet:
|
45
|
+
# https://docs.google.com/spreadsheets/d/1BxiMVs0XRA5nFMdKvBdBZjgmUUqptlbs74OgvE2upms/edit
|
46
|
+
spreadsheet_id = '1YfsXVfFfPHjsry7zBwplFIP4T1ZwAgswZhG4EPWriqM'
|
47
|
+
range = 'Class Data!A2:E'
|
48
|
+
response = service.get_spreadsheet_values(spreadsheet_id, range)
|
49
|
+
puts 'Name, Major:'
|
50
|
+
puts 'No data found.' if response.values.empty?
|
51
|
+
response.values.each do |row|
|
52
|
+
# Print columns A and E, which correspond to indices 0 and 4.
|
53
|
+
puts "#{row[0]}, #{row[4]}"
|
54
|
+
end
|
55
|
+
|
56
|
+
|
@@ -0,0 +1 @@
|
|
1
|
+
../credentials.json
|
data/comptes/token.yaml
ADDED
@@ -0,0 +1,2 @@
|
|
1
|
+
---
|
2
|
+
default: '{"client_id":"811549868817-3u056164jo9hm1k0kka52ddu66f5ulmj.apps.googleusercontent.com","access_token":"ya29.GluKBnE4aZyHRIoFwuq7wJICm1Zy0TuHSOzk13e8KBIQ5mmiv3xdotLtu8_tB8eNQ4dV9Vmu72hPwauy1eerQcdJ03rWCNlczUoJM81bJJ14MmAD2JDeXVm4Hz-6","refresh_token":"1/bwDAU6cva05vQbZae25zN977MovjfavM-X6v3GvVKLs","scope":["https://www.googleapis.com/auth/spreadsheets"],"expiration_time_millis":1546875735000}'
|
data/credentials.json
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
{"installed":{"client_id":"811549868817-3u056164jo9hm1k0kka52ddu66f5ulmj.apps.googleusercontent.com","project_id":"my-project-1546798254686","auth_uri":"https://accounts.google.com/o/oauth2/auth","token_uri":"https://www.googleapis.com/oauth2/v3/token","auth_provider_x509_cert_url":"https://www.googleapis.com/oauth2/v1/certs","client_secret":"gejMFXkEP51dS9TMS-FuTzil","redirect_uris":["urn:ietf:wg:oauth:2.0:oob","http://localhost"]}}
|
data/elements.rb
ADDED
@@ -0,0 +1,111 @@
|
|
1
|
+
module ChartReader
|
2
|
+
|
3
|
+
class Element
|
4
|
+
attr_reader :id, :page_id
|
5
|
+
attr_reader :text, :type
|
6
|
+
|
7
|
+
attr_reader :page
|
8
|
+
attr_reader :initial, :hidden
|
9
|
+
|
10
|
+
def initialize(entry)
|
11
|
+
@id = entry["Id"]
|
12
|
+
@type = entry["Name"]
|
13
|
+
@text = entry["Text Area 1"]
|
14
|
+
@page_id = entry["Page ID"]
|
15
|
+
@link_to = {}
|
16
|
+
@link_from = {}
|
17
|
+
@initial = false
|
18
|
+
end
|
19
|
+
|
20
|
+
def set_initial ; @initial = true; end
|
21
|
+
def is_initial? ; @initial; end
|
22
|
+
|
23
|
+
def hide ; @hidden = true; end
|
24
|
+
def is_hidden? ; @hidden; end
|
25
|
+
|
26
|
+
def is_state?
|
27
|
+
|
28
|
+
# not is_hidden? and has_links? and not text.nil?
|
29
|
+
return false if is_hidden? or not has_links?
|
30
|
+
|
31
|
+
if text.nil?
|
32
|
+
type.eql? "transition"
|
33
|
+
else
|
34
|
+
true
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
def link_to(element, link)
|
39
|
+
@link_to[link] = element
|
40
|
+
end
|
41
|
+
|
42
|
+
def link_from(element, link)
|
43
|
+
@link_from[link] = element
|
44
|
+
end
|
45
|
+
|
46
|
+
def links_to; @link_to; end
|
47
|
+
def links_from; @link_from; end
|
48
|
+
|
49
|
+
def links_to_type(type)
|
50
|
+
@link_to.each_value.select{ |b| b.type.eql? type }
|
51
|
+
end
|
52
|
+
|
53
|
+
def links_from_type(type)
|
54
|
+
@link_from.each_value.select{ |b| b.type.eql? type }
|
55
|
+
end
|
56
|
+
|
57
|
+
|
58
|
+
def has_links?
|
59
|
+
@link_to.size != 0 or @link_from.size != 0
|
60
|
+
end
|
61
|
+
|
62
|
+
def set_page(p)
|
63
|
+
@page = p
|
64
|
+
end
|
65
|
+
|
66
|
+
def to_s
|
67
|
+
"Element: " + @id
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
class Page < Element
|
72
|
+
attr_reader :name
|
73
|
+
attr_reader :blocks
|
74
|
+
|
75
|
+
def initialize(entry)
|
76
|
+
super(entry)
|
77
|
+
puts "ERROR: You cannot create this page" unless is_page? entry
|
78
|
+
@name = entry["Text Area 1"]
|
79
|
+
@blocks = {}
|
80
|
+
end
|
81
|
+
|
82
|
+
def set_block(id, block)
|
83
|
+
@blocks[id] = block
|
84
|
+
block.set_page(self)
|
85
|
+
end
|
86
|
+
|
87
|
+
def to_s
|
88
|
+
"Page: " + @name.to_s
|
89
|
+
end
|
90
|
+
|
91
|
+
end
|
92
|
+
|
93
|
+
class Link < Element
|
94
|
+
attr_reader :source, :destination
|
95
|
+
attr_reader :source_arrow, :destination_arrow
|
96
|
+
|
97
|
+
def initialize(entry)
|
98
|
+
super(entry)
|
99
|
+
@source = entry["Line Source"]
|
100
|
+
@destination = entry["Line Destination"]
|
101
|
+
|
102
|
+
@source_arrow = entry["Source Arrow"]
|
103
|
+
@destination_arrow= entry["Destination Arrow"]
|
104
|
+
end
|
105
|
+
|
106
|
+
def to_s
|
107
|
+
"Link : " + @source.to_s + " -> " + @destination.to_s
|
108
|
+
end
|
109
|
+
end
|
110
|
+
|
111
|
+
end
|
data/exe/lucidMachines
ADDED
data/exporter.rb
ADDED
@@ -0,0 +1,41 @@
|
|
1
|
+
module ChartReader
|
2
|
+
|
3
|
+
class JobTest
|
4
|
+
include AASM
|
5
|
+
def tie_shoes
|
6
|
+
puts "Tying the shoes ..."
|
7
|
+
end
|
8
|
+
end
|
9
|
+
|
10
|
+
def export_all(chart)
|
11
|
+
chart.pages.each_value do |p|
|
12
|
+
export(chart, p.name)
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
def export(chart, page_name)
|
17
|
+
p_ex2 = chart.page page_name
|
18
|
+
page = chart.subchart_for_page p_ex2
|
19
|
+
|
20
|
+
# export GraphViz 1
|
21
|
+
GraphVizExport.new(page).build_graph("export/chart-#{page_name}.png")
|
22
|
+
|
23
|
+
# export AASM
|
24
|
+
page_aasm_export = AASMExport.new(page)
|
25
|
+
|
26
|
+
# export to a file
|
27
|
+
open("export/#{page_name}_generated.rb", 'w') do |f|
|
28
|
+
f << page_aasm_export.export
|
29
|
+
f << page_aasm_export.generate_methods_placeholder
|
30
|
+
end
|
31
|
+
|
32
|
+
# export GraphViz 2 (through aasm-diagram)
|
33
|
+
|
34
|
+
## Extend the JobTest class
|
35
|
+
# JobTest.class_eval page_aasm_export.export
|
36
|
+
# page_aasm_export.generate_methods_placeholder_for(JobTest)
|
37
|
+
# @j = JobTest.new
|
38
|
+
# AASMDiagram::Diagram.new(@j.aasm, "export/chart-#{page_name}-2.png")
|
39
|
+
|
40
|
+
end
|
41
|
+
end
|
data/graphviz_export.rb
ADDED
@@ -0,0 +1,75 @@
|
|
1
|
+
module ChartReader
|
2
|
+
|
3
|
+
class GraphVizExport
|
4
|
+
def initialize(chart)
|
5
|
+
@chart = chart
|
6
|
+
@g = GraphViz.new( :G, :type => :digraph )
|
7
|
+
|
8
|
+
@node_map = {}
|
9
|
+
@edge_map = {}
|
10
|
+
end
|
11
|
+
|
12
|
+
def build_graph(output_name)
|
13
|
+
create_nodes
|
14
|
+
create_edges
|
15
|
+
@g.output( :png => output_name )
|
16
|
+
end
|
17
|
+
|
18
|
+
def create_nodes
|
19
|
+
@chart.states.each do |b|
|
20
|
+
|
21
|
+
n = @g.add_node(b.id)
|
22
|
+
@node_map[b] = n
|
23
|
+
|
24
|
+
n[:label] = b.text.to_s
|
25
|
+
n[:color] = "purple" if b.is_initial?
|
26
|
+
n[:shape] = "box" # look like lucid@chart
|
27
|
+
|
28
|
+
n[:shape] = "diamond" if b.type.eql? "event"
|
29
|
+
n[:shape] = "circle" if b.type.eql? "transition"
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
def create_edges
|
34
|
+
@chart.states.each do |b|
|
35
|
+
|
36
|
+
src = @node_map[b]
|
37
|
+
|
38
|
+
b.links_to.each do |link, b2|
|
39
|
+
|
40
|
+
next unless b2.is_state?
|
41
|
+
|
42
|
+
dst = @node_map[b2]
|
43
|
+
next if b2.is_hidden?
|
44
|
+
e = @g.add_edges(src, dst)
|
45
|
+
|
46
|
+
# b.add_edge(e)
|
47
|
+
@edge_map[b] = [] if @edge_map[b].nil?
|
48
|
+
@edge_map[b] << e
|
49
|
+
|
50
|
+
# style
|
51
|
+
e[:arrowhead] = get_arrow_style(link.destination_arrow)
|
52
|
+
e[:arrowtail] = get_arrow_style(link.source_arrow)
|
53
|
+
|
54
|
+
# if link.source_arrow.eql? "None"
|
55
|
+
|
56
|
+
unless link.text.nil?
|
57
|
+
e[:label] = link.text
|
58
|
+
e[:color] = "red" if link.text.eql? "No"
|
59
|
+
e[:color] = "green" if link.text.eql? "Yes"
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
def get_arrow_style(lucid_style)
|
66
|
+
return "none" if lucid_style.eql? "None"
|
67
|
+
return "normal" if lucid_style.eql? "Arrow"
|
68
|
+
return "empty" if lucid_style.eql? "Hollow Arrow"
|
69
|
+
return "open" if lucid_style.eql? "Open Arrow"
|
70
|
+
|
71
|
+
return "none"
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
end
|