mushy 0.7.0 → 0.13.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 32162cc00416efb4669436924df21b3cc80d59c2ec11b243f0210125e3bcb6dc
4
- data.tar.gz: 0e6e74b96b1988ad3c8792d0e42fdc1dd4a095247e7517429454692b152ddc23
3
+ metadata.gz: 85eb693e91e6a27ab2943d07ab5d4a7d3544c958793aac1830a3d03a81d98001
4
+ data.tar.gz: be51f8e5b94fb4184c1e8f7ba037de1a5ae9901a0fd7ace4fc85e6cc182a864b
5
5
  SHA512:
6
- metadata.gz: 7c89eaf89944c50a8478a8e0b0419ea8cad1f283bb18eb55edd9f38b59ad8c282895f94bac14b697a2e003225ec61cc169642cd1c1f6eeff009084f04094b3d9
7
- data.tar.gz: dcb83c01e8da06d5d896c646a839b4e8b764fc3bba4d7d6393998c2670b7bd7c54d6bf2feeb9999cd85993cdf3afaa8ab778ebe57e37a84ec5a718f0246f984c
6
+ metadata.gz: 8bc9319d1c55c581d91377c28ec526ec2215c66962eae0723cfa47eaca5599d6a5bebc439ce423864c37544e6b6250354235f14dddb182c370836c9a289ddd66
7
+ data.tar.gz: '08efdce27c2820c503ef940224c9b27da0d4c88f11d3f837d50ca1ba99f062de019b1143dc4a3d5bf575b1789b9218c913315570ef00d82b7173c0cbbaa8299a'
data/lib/mushy.rb CHANGED
@@ -3,9 +3,16 @@ require 'symbolized'
3
3
 
4
4
  Dir[File.dirname(__FILE__) + '/mushy/*.rb'].each { |f| require f }
5
5
 
6
- important_flux_files = ['bash', 'browser'].map { |x| "#{x}.rb" }
6
+ important_flux_files = [
7
+ 'bash',
8
+ 'browser',
9
+ 'simple_python_program',
10
+ ].map { |x| "#{x}.rb" }
11
+
7
12
  Dir[File.dirname(__FILE__) + '/mushy/fluxs/*.rb']
8
- .sort_by { |f| important_flux_files.any? { |x| f.end_with?(x) } ? 0 : 1 }
9
- .each { |f| require f }
13
+ .map { |x| [x, important_flux_files.find_index(x.split("\/")[-1]) || 9999999] }
14
+ .sort_by { |x| x[1] }
15
+ .map { |x| x[0] }
16
+ .each { |f| require f }
10
17
 
11
18
  Dir[File.dirname(__FILE__) + '/mushy/builder/*.rb'].each { |f| require f }
data/lib/mushy/flow.rb CHANGED
@@ -17,15 +17,28 @@ module Mushy
17
17
  .flatten
18
18
  end
19
19
 
20
+ def adjust_data data
21
+ fluxs
22
+ .select { |x| x.respond_to? :adjust_data }
23
+ .reduce(data) { |t, i| i.adjust_data t }
24
+ end
25
+
20
26
  def self.build_flux record
21
27
  type = record[:type] || record['type'] || record[:flux] || record['flux'] || 'Flux'
22
28
  flux = Object.const_get("Mushy::#{type}").new
23
29
  flux.id = record[:id] || record['id'] || flux.id
24
30
  flux.type = type
25
31
  flux.config = SymbolizedHash.new(record[:config] || record['config'])
32
+ flux.flow = Mushy::Flow.new
26
33
  flux
27
34
  end
28
35
 
36
+ def build_flux record
37
+ Mushy::Flow.build_flux(record).tap do |flux|
38
+ flux.flow = self
39
+ end
40
+ end
41
+
29
42
  def self.parse data
30
43
  data = JSON.parse data
31
44
 
@@ -34,7 +47,7 @@ module Mushy
34
47
 
35
48
  flow = new
36
49
 
37
- flow.fluxs = data_fluxs.map { |s| build_flux s }
50
+ flow.fluxs = data_fluxs.map { |s| flow.build_flux s }
38
51
 
39
52
  fluxs_with_parent_ids = flow.fluxs.reduce({}) { |t, i| t[i.id] = []; t }
40
53
  data_fluxs.map { |r| fluxs_with_parent_ids[r['id']] = r['parents'] || [] }
data/lib/mushy/flux.rb CHANGED
@@ -8,6 +8,7 @@ module Mushy
8
8
  attr_accessor :subscribed_to
9
9
  attr_accessor :config
10
10
  attr_accessor :masher
11
+ attr_accessor :flow
11
12
 
12
13
  def initialize
13
14
  guard
@@ -39,20 +40,18 @@ module Mushy
39
40
 
40
41
  incoming_event = SymbolizedHash.new(incoming_event) if incoming_event.is_a?(Hash)
41
42
 
42
- event = incoming_event
43
-
44
- incoming_split = masher.mash(config, event)[:incoming_split]
43
+ incoming_split = masher.mash(config, incoming_event)[:incoming_split]
45
44
  config_considering_an_imcoming_split = config
46
45
  .reject { |x, _| incoming_split && x.to_s == 'join' }
47
46
  .reduce({}) { |t, i| t[i[0]] = i[1]; t }
48
47
 
49
- events = incoming_split ? incoming_event[incoming_split] : [event]
48
+ events = incoming_split ? incoming_event[incoming_split] : [incoming_event]
50
49
 
51
50
  results = events.map { |e| execute_single_event e, config_considering_an_imcoming_split }
52
51
 
53
52
  return results.first unless incoming_split
54
53
 
55
- results = join_these_results([results].flatten, event, config[:join]) if config[:join]
54
+ results = join_these_results([results].flatten, incoming_event, config[:join]) if config[:join]
56
55
 
57
56
  results.flatten
58
57
  end
@@ -2,8 +2,6 @@ module Mushy
2
2
 
3
3
  class Collection < Flux
4
4
 
5
- attr_accessor :collection
6
-
7
5
  def self.details
8
6
  {
9
7
  name: 'Collection',
@@ -11,9 +9,14 @@ module Mushy
11
9
  config: {
12
10
  id: {
13
11
  description: 'The path to the unique id in the body of the element.',
14
- type: 'id',
15
- value: { url: 'a|@href' },
12
+ type: 'text',
13
+ value: '{{id}}',
16
14
  },
15
+ collection_name: {
16
+ description: 'The name of the collection to interact with.',
17
+ type: 'text',
18
+ value: 'records',
19
+ },
17
20
  operation: {
18
21
  description: 'Perform this operation.',
19
22
  type: 'select',
@@ -24,31 +27,26 @@ module Mushy
24
27
  }
25
28
  end
26
29
 
27
- def initialize
28
- self.collection = {}
29
- super
30
- end
31
-
32
30
  def process event, config
33
31
  self.send(config[:operation].to_sym, event, config)
34
32
  end
35
33
 
36
34
  def get_the_id event, config
37
- event[config[:id]]
35
+ config[:id]
38
36
  end
39
37
 
40
38
  def all event, config
41
- self.collection.values
39
+ the_collection(config).values
42
40
  end
43
41
 
44
42
  def delete event, config
45
- self.collection.delete get_the_id(event, config)
43
+ the_collection(config).delete get_the_id(event, config)
46
44
  event[config[:operation_performed]] = 'deleted' if config[:operation_performed]
47
45
  event
48
46
  end
49
47
 
50
48
  def upsert event, config
51
- if self.collection[get_the_id(event, config)]
49
+ if the_collection(config)[get_the_id(event, config)]
52
50
  update event, config
53
51
  else
54
52
  insert event, config
@@ -56,18 +54,38 @@ module Mushy
56
54
  end
57
55
 
58
56
  def update event, config
59
- item = self.collection[get_the_id(event, config)]
57
+ item = the_collection(config)[get_the_id(event, config)]
60
58
  event.each { |k, v| item[k] = v } if item
61
59
  event[config[:operation_performed]] = (item ? 'updated' : 'not exist') if config[:operation_performed]
62
60
  event
63
61
  end
64
62
 
65
63
  def insert event, config
66
- self.collection[get_the_id(event, config)] = event
64
+ the_collection(config)[get_the_id(event, config)] = event
67
65
  event[config[:operation_performed]] = 'inserted' if config[:operation_performed]
68
66
  event
69
67
  end
70
68
 
69
+ def the_collection config
70
+ Mushy::Collection.guard_the_flow self.flow
71
+ the_collection_name = config[:collection_name]
72
+
73
+ get_the_collection the_collection_name
74
+ end
75
+
76
+ def get_the_collection name
77
+ found_collection = self.flow.collection_data[name]
78
+ return found_collection if found_collection
79
+ self.flow.collection_data[name] = SymbolizedHash.new
80
+ end
81
+
82
+ def self.guard_the_flow flow
83
+ return if flow.respond_to?(:collection_data)
84
+
85
+ flow.instance_eval { class << self; self end }.send(:attr_accessor, :collection_data)
86
+ flow.collection_data = {}
87
+ end
88
+
71
89
  end
72
90
 
73
91
  end
@@ -0,0 +1,39 @@
1
+ module Mushy
2
+
3
+ class GlobalVariables < Flux
4
+
5
+ attr_accessor :state
6
+
7
+ def self.details
8
+ {
9
+ name: 'GlobalVariables',
10
+ description: 'Add global variables.',
11
+ config: {
12
+ values: {
13
+ description: 'Provide key/value pairs that will be set as global variables.',
14
+ label: 'Variables',
15
+ type: 'keyvalue',
16
+ value: {},
17
+ },
18
+ },
19
+ }
20
+ end
21
+
22
+ def initialize
23
+ super
24
+ self.state = SymbolizedHash.new
25
+ end
26
+
27
+ def adjust_data data
28
+ state.merge data
29
+ end
30
+
31
+ def process event, config
32
+ values = config[:values] || SymbolizedHash.new
33
+ state.merge! values
34
+ event
35
+ end
36
+
37
+ end
38
+
39
+ end
@@ -4,8 +4,8 @@ module Mushy
4
4
 
5
5
  def self.details
6
6
  details = Browser.details
7
- details['name'] = 'Pdf'
8
- details['description'] = 'Turn a URL into a PDF.'
7
+ details[:name] = 'Pdf'
8
+ details[:description] = 'Turn a URL into a PDF.'
9
9
 
10
10
  details[:config][:path] = {
11
11
  description: 'The path of the PDF file to save.',
@@ -0,0 +1,28 @@
1
+ require 'csv'
2
+
3
+ module Mushy
4
+
5
+ class ReadJson < Flux
6
+
7
+ def self.details
8
+ {
9
+ name: 'ReadJson',
10
+ description: 'Read JSON and output it as an event.',
11
+ config: {
12
+ json: {
13
+ description: 'The JSON contents that will be returned as an event.',
14
+ type: 'text',
15
+ value: 'json',
16
+ },
17
+ },
18
+ }
19
+ end
20
+
21
+ def process event, config
22
+ return nil unless config[:json].to_s != ''
23
+ JSON.parse config[:json]
24
+ end
25
+
26
+ end
27
+
28
+ end
@@ -4,8 +4,8 @@ module Mushy
4
4
 
5
5
  def self.details
6
6
  details = Browser.details
7
- details['name'] = 'Screenshot'
8
- details['description'] = 'Take a screenshot of the browser.'
7
+ details[:name] = 'Screenshot'
8
+ details[:description] = 'Take a screenshot of the browser.'
9
9
 
10
10
  details[:config].merge!(Mushy::WriteFile.file_saving_config.tap do |x|
11
11
  x[x.keys.first][:value] = 'file.jpg'
@@ -0,0 +1,56 @@
1
+ module Mushy
2
+
3
+ class SenseHatEnvironmentalSensors < SimplePythonProgram
4
+
5
+ def self.details
6
+ {
7
+ name: 'SenseHatEnvironmentalSensors',
8
+ description: 'Pull values from the Sense HAT environmental sensors.',
9
+ config: Mushy::SimplePythonProgram.default_config,
10
+ }.tap do |c|
11
+ measurements
12
+ .sort_by { |x| default_measurements.include?(x) ? 0 : 1 }
13
+ .each do |measurement|
14
+ c[:config][measurement] = {
15
+ description: "Pull #{measurement}.",
16
+ type: 'boolean',
17
+ shrink: true,
18
+ value: default_measurements.include?(measurement) ? 'true' : '',
19
+ }
20
+ end
21
+ end
22
+ end
23
+
24
+ def self.measurements
25
+ [
26
+ :humidity,
27
+ :temperature,
28
+ :temperature_from_humidity,
29
+ :temperature_from_pressure,
30
+ :pressure,
31
+ ]
32
+ end
33
+
34
+ def self.default_measurements
35
+ [:humidity, :temperature, :pressure]
36
+ end
37
+
38
+ def python_program event, config
39
+ values = self.class.measurements
40
+ .select { |x| config[x] == 'true' }
41
+ .reduce({}) { |t, i| t[i] = "get_#{i}"; t}
42
+ .map { |m| "\"#{m[0]}\": sense.#{m[1]}()" }
43
+ .join(',')
44
+
45
+ <<PYTHON
46
+ from sense_hat import SenseHat
47
+ import json
48
+ sense = SenseHat()
49
+ value = json.dumps({#{values}})
50
+ print(value)
51
+ PYTHON
52
+ end
53
+
54
+ end
55
+
56
+ end
@@ -0,0 +1,283 @@
1
+ module Mushy
2
+
3
+ class SenseHatLedMatrix < SimplePythonProgram
4
+
5
+ def self.details
6
+ {
7
+ name: 'SenseHatLedMatrix',
8
+ description: 'Interface with the LED Matrix.',
9
+ config: Mushy::SimplePythonProgram.default_config.tap do |config|
10
+ config[:get_pixels] = {
11
+ description: 'Specify the pixels you want returned as events. Use "all" to return all 64, 3,3 to return x:3 y:3, or "none" to return none.',
12
+ type: 'text',
13
+ shrink: true,
14
+ value: 'all',
15
+ }
16
+ config[:set_pixel] = {
17
+ description: 'Set a single pixel to the RGB color.',
18
+ type: 'text',
19
+ shrink: true,
20
+ value: '',
21
+ }
22
+ config[:set_pixels] = {
23
+ description: 'An array of multiple pixels to set. The records must have coordinates and rgb values, just like what comes out of the get pixels call.',
24
+ type: 'text',
25
+ shrink: true,
26
+ value: '',
27
+ }
28
+ config[:rgb] = {
29
+ description: 'The RGB value as a comma-delimited list. Leave blank to not set a color.',
30
+ type: 'text',
31
+ shrink: true,
32
+ value: '',
33
+ }
34
+ config[:background_color] = {
35
+ description: 'The RGB of the background, which is used in some API calls.',
36
+ type: 'text',
37
+ shrink: true,
38
+ value: '',
39
+ }
40
+ config[:clear] = {
41
+ description: 'The RGB color to apply to the entire grid.',
42
+ type: 'text',
43
+ shrink: true,
44
+ value: '',
45
+ }
46
+ config[:show_letter] = {
47
+ description: 'Show a single letter on the grid. Uses Rgb and Background Color.',
48
+ type: 'text',
49
+ shrink: true,
50
+ value: '',
51
+ }
52
+ config[:show_message] = {
53
+ description: 'Scroll a message across the grid. Uses Rgb and Background Color.',
54
+ type: 'text',
55
+ shrink: true,
56
+ value: '',
57
+ }
58
+ config[:load_image] = {
59
+ description: 'Load a 8x8 image.',
60
+ type: 'text',
61
+ shrink: true,
62
+ value: '',
63
+ }
64
+ config[:set_rotation] = {
65
+ description: 'Rotate the image by these degrees.',
66
+ type: 'select',
67
+ options: ['', '0', '90', '180', '270'],
68
+ shrink: true,
69
+ value: '',
70
+ }
71
+ config[:redraw] = {
72
+ description: 'Redraw.',
73
+ type: 'boolean',
74
+ shrink: true,
75
+ value: '',
76
+ }
77
+ config[:low_light] = {
78
+ description: 'Use the low light to turn down the brightness.',
79
+ type: 'boolean',
80
+ shrink: true,
81
+ value: '',
82
+ }
83
+ config[:flip_h] = {
84
+ description: 'Flips the image horizontally.',
85
+ type: 'boolean',
86
+ shrink: true,
87
+ value: '',
88
+ }
89
+ config[:flip_v] = {
90
+ description: 'Flips the image vertically.',
91
+ type: 'boolean',
92
+ shrink: true,
93
+ value: '',
94
+ }
95
+ config[:target] = {
96
+ description: 'The target of these commands. "hat" is a SenseHAT plugged into your Raspberry Pi, and "emu" is the SenseHAT emulator. Defaults to "hat".',
97
+ type: 'select',
98
+ options: ['', 'hat' , 'emu'],
99
+ shrink: true,
100
+ value: '',
101
+ }
102
+ end
103
+ }
104
+ end
105
+
106
+ def python_program event, config
107
+
108
+ commands = [
109
+ :set_pixel_code_from,
110
+ :set_pixels_code_from,
111
+ :clear_pixels_code_from,
112
+ :show_letters_code_from,
113
+ :show_message_code_from,
114
+ :load_images_code_from,
115
+ :set_rotation_code_from,
116
+ :low_light_code_from,
117
+ :flip_h_code_from,
118
+ :flip_v_code_from,
119
+ ].map { |x| self.send x, event, config }
120
+ .select { |x| x.to_s != '' }
121
+ .join("\n")
122
+
123
+ hat = config[:target] == 'emu' ? 'sense_emu' : 'sense_hat'
124
+
125
+ <<PYTHON
126
+ from #{hat} import SenseHat
127
+ import json
128
+ sense = SenseHat()
129
+ #{commands}
130
+ value = json.dumps({"all": #{get_pixels_code_from(event, config)}})
131
+ print(value)
132
+ PYTHON
133
+ end
134
+
135
+ def adjust data, event, config
136
+ limit = 8
137
+
138
+ coordinates = coordinates_from config[:get_pixels]
139
+
140
+ records = coordinates ? [data[:all]] : data[:all]
141
+
142
+ results = records.each_with_index.map do |item, index|
143
+ {
144
+ x: index % limit,
145
+ y: index / limit,
146
+ r: item[0],
147
+ g: item[1],
148
+ b: item[2],
149
+ }
150
+ end
151
+
152
+ if coordinates
153
+ results[0][:x] = coordinates[:x]
154
+ results[0][:y] = coordinates[:y]
155
+ end
156
+
157
+ results.each do |record|
158
+ record[:coordinate] = "#{record[:x]},#{record[:y]}"
159
+ record[:rgb] = "#{record[:r]},#{record[:g]},#{record[:b]}"
160
+ end
161
+
162
+ results
163
+ end
164
+
165
+ def rgb_from config
166
+ color_split = config.to_s.split ','
167
+ return nil unless color_split.count == 3
168
+ return [:r, :g, :b].each_with_index
169
+ .reduce({}) { |t, i| t[i[0]] = color_split[i[1]].to_s.to_i ; t}
170
+ end
171
+
172
+ def coordinates_from config
173
+ coordinate_split = config.to_s.split ','
174
+ return nil unless coordinate_split.count == 2
175
+ return [:x, :y].each_with_index
176
+ .reduce({}) { |t, i| t[i[0]] = coordinate_split[i[1]].to_s.to_i ; t}
177
+ end
178
+
179
+ def set_pixel_code_from event, config
180
+ rgb = rgb_from config[:rgb]
181
+ set_pixel_coordinates = coordinates_from config[:set_pixel]
182
+ return '' unless rgb
183
+ return '' unless set_pixel_coordinates
184
+
185
+ turn_these_to_pixels([ {
186
+ coordinate: "#{set_pixel_coordinates[:x]},#{set_pixel_coordinates[:y]}",
187
+ rgb: "#{rgb[:r]},#{rgb[:g]},#{rgb[:b]}",
188
+ } ])
189
+ end
190
+
191
+ def set_pixels_code_from event, config
192
+ return '' unless config[:set_pixels]
193
+ turn_these_to_pixels config[:set_pixels]
194
+ end
195
+
196
+ def turn_these_to_pixels values
197
+ options = [:coordinate, :rgb]
198
+ values.map do |pixel|
199
+ options.reduce({}) { |t, i| t[i] = pixel[i].split(',') ; t}
200
+ end.map do |pixel|
201
+ "sense.set_pixel(#{pixel[:coordinate][0]}, #{pixel[:coordinate][1]}, [#{pixel[:rgb][0]}, #{pixel[:rgb][1]}, #{pixel[:rgb][2]}])"
202
+ end.join("\n")
203
+ end
204
+
205
+ def clear_pixels_code_from event, config
206
+ clear = rgb_from config[:clear]
207
+ return '' unless clear
208
+ "sense.clear(#{clear[:r]}, #{clear[:g]}, #{clear[:b]})"
209
+ end
210
+
211
+ def show_letters_code_from event, config
212
+ return '' if config[:show_letter].to_s == ''
213
+
214
+ rgb = rgb_from config[:rgb]
215
+ background_color = rgb_from config[:background_color]
216
+
217
+ args = ["\"#{config[:show_letter]}\""]
218
+ args << "text_colour=[#{rgb[:r]}, #{rgb[:g]}, #{rgb[:b]}]" if rgb
219
+ args << "back_colour=[#{background_color[:r]}, #{background_color[:g]}, #{background_color[:b]}]" if background_color
220
+ "sense.show_letter(#{args.join(',')})"
221
+ end
222
+
223
+ def show_message_code_from event, config
224
+ return '' if config[:show_message].to_s == ''
225
+
226
+ rgb = rgb_from config[:rgb]
227
+ background_color = rgb_from config[:background_color]
228
+
229
+ args = ["\"#{config[:show_message]}\""]
230
+ args << "text_colour=[#{rgb[:r]}, #{rgb[:g]}, #{rgb[:b]}]" if rgb
231
+ args << "back_colour=[#{background_color[:r]}, #{background_color[:g]}, #{background_color[:b]}]" if background_color
232
+ "sense.show_message(#{args.join(',')})"
233
+ end
234
+
235
+ def load_images_code_from event, config
236
+ return '' if config[:load_image].to_s == ''
237
+
238
+ args = ["\"#{config[:load_image]}\""]
239
+ args << config[:redraw].to_s.capitalize if config[:redraw].to_s != ''
240
+ "sense.load_image(#{args.join(',')})"
241
+ end
242
+
243
+ def set_rotation_code_from event, config
244
+ return '' if config[:set_rotation].to_s == ''
245
+ args = ["#{config[:set_rotation]}"]
246
+ args << config[:redraw].to_s.capitalize if config[:redraw].to_s != ''
247
+ "sense.set_rotation(#{args.join(',')})"
248
+ end
249
+
250
+ def low_light_code_from event, config
251
+ return '' if config[:low_light].to_s == ''
252
+ "sense.low_light = #{config[:low_light].capitalize}"
253
+ end
254
+
255
+ def flip_h_code_from event, config
256
+ return '' unless config[:flip_h].to_s == 'true'
257
+ args = []
258
+ args << config[:redraw].to_s.capitalize if config[:redraw].to_s != ''
259
+ "sense.flip_h(#{args.join(',')})"
260
+ end
261
+
262
+ def flip_v_code_from event, config
263
+ return '' unless config[:flip_v].to_s == 'true'
264
+ args = []
265
+ args << config[:redraw].to_s.capitalize if config[:redraw].to_s != ''
266
+ "sense.flip_v(#{args.join(',')})"
267
+ end
268
+
269
+ def get_pixels_code_from event, config
270
+ get_pixel_coordinates = coordinates_from config[:get_pixels]
271
+
272
+ if get_pixel_coordinates
273
+ "sense.get_pixel(#{get_pixel_coordinates[:x]}, #{get_pixel_coordinates[:y]})"
274
+ elsif config[:get_pixels].to_s.downcase == 'all'
275
+ 'sense.get_pixels()'
276
+ else
277
+ '[]'
278
+ end
279
+ end
280
+
281
+ end
282
+
283
+ end
@@ -0,0 +1,36 @@
1
+ module Mushy
2
+
3
+ class SimplePythonProgram < Bash
4
+
5
+ def self.default_config
6
+ Mushy::Bash.details[:config].tap do |config|
7
+ config.delete :command
8
+ config.delete :directory
9
+ end
10
+ end
11
+
12
+ def process event, config
13
+
14
+ lines = python_program(event, config)
15
+ .split('\n')
16
+ .map { |x| x.rstrip }
17
+ .select { |x| x && x != '' }
18
+ .map { |x| x.gsub('"', '\"') }
19
+
20
+ config[:command] = "python -c \"#{lines.join(';')}\""
21
+
22
+ result = super event, config
23
+
24
+ return nil unless result[:success]
25
+
26
+ adjust SymbolizedHash.new(JSON.parse(result[:text])), event, config
27
+
28
+ end
29
+
30
+ def adjust data, event, config
31
+ data
32
+ end
33
+
34
+ end
35
+
36
+ end
@@ -0,0 +1,29 @@
1
+ require 'csv'
2
+
3
+ module Mushy
4
+
5
+ class WriteJson < Flux
6
+
7
+ def self.details
8
+ {
9
+ name: 'WriteJson',
10
+ description: 'Write the incoming event as JSON.',
11
+ config: {
12
+ key: {
13
+ description: 'The key of the outgoing field that will contain the JSON.',
14
+ type: 'text',
15
+ value: 'json',
16
+ },
17
+ },
18
+ }
19
+ end
20
+
21
+ def process event, config
22
+ {
23
+ config[:key] => event.to_json
24
+ }
25
+ end
26
+
27
+ end
28
+
29
+ end
data/lib/mushy/masher.rb CHANGED
@@ -45,7 +45,15 @@ module Mushy
45
45
  segments = key.split '.'
46
46
 
47
47
  segments.each do |segment|
48
- data = data.is_a?(Hash) ? (data[segment] || data[segment.to_sym]) : (data ? data.send(segment.to_sym) : nil)
48
+ if segment.include?('[') && segment.include?(']')
49
+ the_splits = segment.split('[')
50
+ segment = the_splits[0]
51
+ index = the_splits[1].sub(']', '')
52
+ data = data.is_a?(Hash) ? (data[segment] || data[segment.to_sym]) : (data ? data.send(segment.to_sym) : nil)
53
+ data = data[index.to_i]
54
+ else
55
+ data = data.is_a?(Hash) ? (data[segment] || data[segment.to_sym]) : (data ? data.send(segment.to_sym) : nil)
56
+ end
49
57
  end
50
58
 
51
59
  data
data/lib/mushy/runner.rb CHANGED
@@ -12,7 +12,7 @@ module Mushy
12
12
  run = find_run flux, flow
13
13
  starting_event = build_event event_data, flow.id, run.id, flux.id
14
14
 
15
- events = run_event_with_flux starting_event, flux
15
+ events = run_event_with_flux starting_event, flux, flow
16
16
 
17
17
  while events.any?
18
18
  events = events.map { |e| runner.run_event_in_flow e, flow }.flatten
@@ -23,12 +23,14 @@ module Mushy
23
23
 
24
24
  def run_event_in_flow event, flow
25
25
  flow.fluxs_for(event)
26
- .map { |s| runner.run_event_with_flux event, s }
26
+ .map { |s| runner.run_event_with_flux event, s, flow }
27
27
  .flatten
28
28
  end
29
29
 
30
- def run_event_with_flux event, flux
31
- [flux.execute(event.data)]
30
+ def run_event_with_flux event, flux, flow
31
+ data = event.data
32
+ data = flow.adjust_data data
33
+ [flux.execute(data)]
32
34
  .flatten
33
35
  .reject { |x| x.nil? }
34
36
  .map { |x| x.is_a?(Hash) ? build_event(x, event.flow_id, event.run_id, flux.id) : x }
data/mushy.gemspec CHANGED
@@ -4,7 +4,7 @@ require 'mushy/version'
4
4
 
5
5
  Gem::Specification.new do |s|
6
6
  s.name = 'mushy'
7
- s.version = '0.7.0'
7
+ s.version = '0.13.0'
8
8
  s.date = '2020-11-23'
9
9
  s.summary = 'Process streams of work using common modules.'
10
10
  s.description = 'This tool assists in the creation and processing of workflows.'
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: mushy
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.7.0
4
+ version: 0.13.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Darren Cauthon
@@ -194,6 +194,7 @@ files:
194
194
  - lib/mushy/fluxs/format.rb
195
195
  - lib/mushy/fluxs/get.rb
196
196
  - lib/mushy/fluxs/git_log.rb
197
+ - lib/mushy/fluxs/global_variables.rb
197
198
  - lib/mushy/fluxs/interval.rb
198
199
  - lib/mushy/fluxs/ls.rb
199
200
  - lib/mushy/fluxs/parse_html.rb
@@ -202,10 +203,15 @@ files:
202
203
  - lib/mushy/fluxs/pwd.rb
203
204
  - lib/mushy/fluxs/read_csv.rb
204
205
  - lib/mushy/fluxs/read_file.rb
206
+ - lib/mushy/fluxs/read_json.rb
205
207
  - lib/mushy/fluxs/screenshot.rb
208
+ - lib/mushy/fluxs/sense_hat_environmental_sensors.rb
209
+ - lib/mushy/fluxs/sense_hat_led_matrix.rb
210
+ - lib/mushy/fluxs/simple_python_program.rb
206
211
  - lib/mushy/fluxs/smtp.rb
207
212
  - lib/mushy/fluxs/times.rb
208
213
  - lib/mushy/fluxs/write_file.rb
214
+ - lib/mushy/fluxs/write_json.rb
209
215
  - lib/mushy/masher.rb
210
216
  - lib/mushy/run.rb
211
217
  - lib/mushy/runner.rb