lucidMachines 0.1.2

Sign up to get free protection for your applications and to get access to all the features.
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)
@@ -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)
@@ -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
@@ -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
@@ -0,0 +1,6 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'lucidMachines'
4
+ require 'lucidMachines/cli'
5
+
6
+ LucidMachines::CLI.start
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
@@ -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