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.
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