mushy 0.7.0 → 0.13.0

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