mushy 0.0.7 → 0.2.1
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 +4 -4
- data/bin/mushy +11 -9
- data/lib/mushy.rb +2 -8
- data/lib/mushy/builder/api.rb +20 -1
- data/lib/mushy/builder/index.rb +124 -42
- data/lib/mushy/flow.rb +3 -1
- data/lib/mushy/flux.rb +1 -0
- data/lib/mushy/fluxs/browser.rb +26 -3
- data/lib/mushy/fluxs/cli.rb +20 -0
- data/lib/mushy/fluxs/filter.rb +23 -0
- data/lib/mushy/fluxs/screenshot.rb +46 -0
- data/mushy.gemspec +2 -2
- metadata +3 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 0a746bd3fc6a56c75327b154456d7fe9539af431ed78480c21bbf022990007f9
|
4
|
+
data.tar.gz: 3b31a72b3ab2a2caab0a93535c4433b77f7b66538f6ee5617a6b2a747af33a95
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 21e699536cb12cfc6108ed415d491f67bd080882dec6a6a58d4a5674ee8b597f2457f4693f34612f504f0b29a2642cc0005e516e80d01c37e4632168e6c948be
|
7
|
+
data.tar.gz: b175f8be7b8f4a87bd5c41235a7f6ca3d88e09ec334b702de67b224947869bf53d4dffe3853eec5e179436f727fa53b170998c7e799ef9a26112c9f513a95de7
|
data/bin/mushy
CHANGED
@@ -3,18 +3,20 @@
|
|
3
3
|
require 'thor'
|
4
4
|
require 'mushy'
|
5
5
|
|
6
|
-
class
|
6
|
+
class MushyCLI < Thor
|
7
|
+
|
8
|
+
argument :file, optional: true, type: :string
|
9
|
+
argument :values, optional: true, type: :hash
|
7
10
|
|
8
11
|
desc "start FILE", "Run this workflow file."
|
9
|
-
def start
|
10
|
-
|
11
|
-
puts content
|
12
|
+
def start
|
13
|
+
Mushy::Builder::Api.start file, values
|
12
14
|
end
|
13
15
|
|
14
16
|
desc "build FILE", 'Build a flow.'
|
15
|
-
def build
|
17
|
+
def build
|
16
18
|
|
17
|
-
|
19
|
+
MushyCLI.set_special( { method: 'build', file: file } )
|
18
20
|
|
19
21
|
end
|
20
22
|
|
@@ -28,14 +30,14 @@ class RailsCLI < Thor
|
|
28
30
|
|
29
31
|
end
|
30
32
|
|
31
|
-
|
33
|
+
MushyCLI.start(ARGV)
|
32
34
|
|
33
|
-
exit unless
|
35
|
+
exit unless MushyCLI.get_special
|
34
36
|
|
35
37
|
require 'sinatra'
|
36
38
|
enable :run
|
37
39
|
|
38
|
-
the_file =
|
40
|
+
the_file = MushyCLI.get_special[:file]
|
39
41
|
|
40
42
|
get '/' do
|
41
43
|
Mushy::Builder::Index.file
|
data/lib/mushy.rb
CHANGED
@@ -3,15 +3,9 @@ require 'symbolized'
|
|
3
3
|
|
4
4
|
Dir[File.dirname(__FILE__) + '/mushy/*.rb'].each { |f| require f }
|
5
5
|
|
6
|
-
important_flux_files = ['bash'].map { |x| "#{x}.rb" }
|
6
|
+
important_flux_files = ['bash', 'browser'].map { |x| "#{x}.rb" }
|
7
7
|
Dir[File.dirname(__FILE__) + '/mushy/fluxs/*.rb']
|
8
8
|
.sort_by { |f| important_flux_files.any? { |x| f.end_with?(x) } ? 0 : 1 }
|
9
9
|
.each { |f| require f }
|
10
10
|
|
11
|
-
Dir[File.dirname(__FILE__) + '/mushy/builder/*.rb'].each { |f| require f }
|
12
|
-
|
13
|
-
module Mushy
|
14
|
-
def self.hi
|
15
|
-
puts 'hello'
|
16
|
-
end
|
17
|
-
end
|
11
|
+
Dir[File.dirname(__FILE__) + '/mushy/builder/*.rb'].each { |f| require f }
|
data/lib/mushy/builder/api.rb
CHANGED
@@ -28,10 +28,29 @@ module Mushy
|
|
28
28
|
|
29
29
|
end
|
30
30
|
|
31
|
+
def self.start file, event
|
32
|
+
file = "#{file}.json" unless file.downcase.end_with?('.json')
|
33
|
+
flow = File.open(file).read
|
34
|
+
flow = Mushy::Flow.parse flow
|
35
|
+
flux = flow.fluxs.select { |x| x.type == 'Cli' }.first
|
36
|
+
|
37
|
+
Mushy::Runner.new.start event, flux, flow
|
38
|
+
end
|
39
|
+
|
31
40
|
def self.get_flow file
|
32
41
|
puts "trying to get: #{file}"
|
33
42
|
file = "#{file}.json" unless file.downcase.end_with?('.json')
|
34
|
-
JSON.parse File.open(file).read
|
43
|
+
data = JSON.parse File.open(file).read
|
44
|
+
data['fluxs']
|
45
|
+
.reject { |x| x['parents'] }
|
46
|
+
.each { |x| x['parents'] = [x['parent']].select { |y| y } }
|
47
|
+
data['fluxs']
|
48
|
+
.select { |x| x['parent'] }
|
49
|
+
.each { |x| x.delete 'parent' }
|
50
|
+
data['fluxs']
|
51
|
+
.select { |x| x['parents'] }
|
52
|
+
.each { |x| x['parents'] = x['parents'].select { |y| y } }
|
53
|
+
data
|
35
54
|
rescue
|
36
55
|
{ fluxs: [] }
|
37
56
|
end
|
data/lib/mushy/builder/index.rb
CHANGED
@@ -15,22 +15,23 @@ module Mushy
|
|
15
15
|
<table v-if="setup.showFlux == false">
|
16
16
|
<tr>
|
17
17
|
<th>Name</th>
|
18
|
-
<th>
|
18
|
+
<th>Receives Events From</th>
|
19
19
|
<th>Actions</th>
|
20
20
|
</tr>
|
21
21
|
<tr v-for="flux in flow.fluxs">
|
22
22
|
<td>{{flux.name}}</td>
|
23
|
-
<td>{{flux_name_for(flux.
|
24
|
-
<td
|
23
|
+
<td>{{flux_name_for(flux.parents, flow.fluxs)}}</td>
|
24
|
+
<td>
|
25
|
+
<button v-on:click.prevent.stop="editFlux({ flux: flux, setup: setup, configs: configs })">Edit</button>
|
26
|
+
<button v-on:click.prevent.stop="deleteFlux({ flux: flux, flow: flow })">Delete</button>
|
27
|
+
</td>
|
25
28
|
</tr>
|
26
29
|
</table>
|
27
|
-
<button v-if="setup.showFlux == false" v-on:click.prevent.stop="startNew({ setup: setup, configs: configs })">
|
28
|
-
<button v-if="setup.showFlux == false" v-on:click.prevent.stop="saveFlow({ setup: setup, flow: flow })">Save This Flow</button>
|
29
|
-
<button v-if="setup.showFlux" v-on:click.prevent.stop="setup.showFlux = false">< Go Back To List</button>
|
30
|
+
<button v-if="setup.showFlux == false" v-on:click.prevent.stop="startNew({ setup: setup, configs: configs })">Add a New Flux To This Flow</button>
|
30
31
|
<div v-if="setup.showFlux">
|
31
32
|
<mip-heavy :data="setup"></mip-heavy>
|
32
33
|
<mip-heavy v-for="(data, id) in configs" v-show="setup.flux.value === id" :data="data"></mip-heavy>
|
33
|
-
<div v-if="results.
|
34
|
+
<div v-if="results.errorMessage">{{results.errorMessage}}</div>
|
34
35
|
<div v-else>{{results.length}} result{{results.length == 1 ? "" : "s"}}</div>
|
35
36
|
<mip-heavy v-for="data in results" :data="data"></mip-heavy>
|
36
37
|
</div>
|
@@ -57,6 +58,22 @@ module Mushy
|
|
57
58
|
props: ['label', 'description', 'hide_description'],
|
58
59
|
template: '<label :for="id" v-if="label != \\'\\'">{{label || ' + fancyName('id') + '}} <i v-show="description && !hide_description">({{description}})</i></label>'
|
59
60
|
},
|
61
|
+
h1: {
|
62
|
+
props: ['label', 'description', 'hide_description'],
|
63
|
+
template: '<h1 v-if="label != \\'\\'">{{label || ' + fancyName('id') + '}} <i v-show="description && !hide_description">({{description}})</i></h1>'
|
64
|
+
},
|
65
|
+
h2: {
|
66
|
+
props: ['label', 'description', 'hide_description'],
|
67
|
+
template: '<h2 v-if="label != \\'\\'">{{label || ' + fancyName('id') + '}} <i v-show="description && !hide_description">({{description}})</i></h2>'
|
68
|
+
},
|
69
|
+
h3: {
|
70
|
+
props: ['label', 'description', 'hide_description'],
|
71
|
+
template: '<h3 v-if="label != \\'\\'">{{label || ' + fancyName('id') + '}} <i v-show="description && !hide_description">({{description}})</i></h3>'
|
72
|
+
},
|
73
|
+
h4: {
|
74
|
+
props: ['label', 'description', 'hide_description'],
|
75
|
+
template: '<h4 v-if="label != \\'\\'">{{label || ' + fancyName('id') + '}} <i v-show="description && !hide_description">({{description}})</i></h4>'
|
76
|
+
},
|
60
77
|
text: {
|
61
78
|
props: ['label', 'placeholder', 'disabled', 'readonly', 'value', 'description', 'shrink'],
|
62
79
|
template: '<div><mip-label :id="id" :label="label" :description="description" :hide_description="shrink"></mip-label> <a href="#" v-on:click.prevent.stop="shrink=false" v-show="shrink && !value">[^]</a><input type="text" :name="id" v-if="value || !shrink" :placeholder="placeholder" v-bind:value="value" v-on:input="$emit(\\'update:value\\', $event.target.value);" :disabled="disabled == \\'true\\'" :readonly="readonly == \\'true\\'"></div>'
|
@@ -90,7 +107,7 @@ module Mushy
|
|
90
107
|
};
|
91
108
|
},
|
92
109
|
props: ['label', 'placeholder', 'disabled', 'readonly', 'value', 'description', 'view'],
|
93
|
-
template: '<div><mip-
|
110
|
+
template: '<div><mip-h4 :id="id" :label="label" :description="description"></mip-h4> <pre><code>{{show(view, value)}}</code></pre><button :disabled="view==\\'beautiful\\'" v-on:click.prevent.stop="view=toggle(view)">View Pretty</button><button :disabled="view!=\\'beautiful\\'" v-on:click.prevent.stop="view=toggle(view)">View Smaller</button><button v-on:click.prevent.stop="copy(view, value)">Copy</button></div>'
|
94
111
|
},
|
95
112
|
radio: {
|
96
113
|
props: ['label', 'value', 'options', 'description', 'shrink'],
|
@@ -104,6 +121,32 @@ module Mushy
|
|
104
121
|
props: ['label', 'value', 'options', 'description', 'shrink'],
|
105
122
|
template: '<div><mip-label :id="id" :label="label" :description="description" :hide_description="shrink"></mip-label> <a href="#" v-on:click.prevent.stop="shrink=false" v-show="shrink && !value">[^]</a><select :name="id" v-if="value || !shrink" v-on:input="$emit(\\'update:value\\', $event.target.value)"><option v-for="option in options" v-bind:value="option.id" :selected="value == option.id">{{option.name}}</option></select></div>'
|
106
123
|
},
|
124
|
+
selectmanyrecords: {
|
125
|
+
data: function() {
|
126
|
+
return {
|
127
|
+
selectedValue: '',
|
128
|
+
remove: function(value, set) {
|
129
|
+
if (set.includes(value) == false) return;
|
130
|
+
for(var i = 0; i < set.length; i++)
|
131
|
+
{
|
132
|
+
if (set[i] === value)
|
133
|
+
{
|
134
|
+
set.splice(i, 1);
|
135
|
+
i--;
|
136
|
+
}
|
137
|
+
}
|
138
|
+
return set;
|
139
|
+
},
|
140
|
+
doit: function(value, set) {
|
141
|
+
if (set.includes(value) == false)
|
142
|
+
set.push(value);
|
143
|
+
return set;
|
144
|
+
},
|
145
|
+
};
|
146
|
+
},
|
147
|
+
props: ['label', 'value', 'options', 'description', 'shrink'],
|
148
|
+
template: '<div><mip-label :id="id" :label="label" :description="description" :hide_description="shrink"></mip-label> <a href="#" v-on:click.prevent.stop="shrink=false" v-show="shrink && !value">[^]</a> <span v-for="option in options" v-if="value && value.includes(option.id)">{{option.name}} <a href="#" v-on:click.prevent.stop="remove(option.id, value);$emit(\\'update:value\\', value)">[X]</a> </span> <a href="#" v-on:click.prevent.stop="doit(selectedValue, value);$emit(\\'update:value\\', value)">ADD</a> <select :name="id" v-if="value || !shrink" v-on:input="selectedValue=$event.target.value;"><option v-for="option in options" v-bind:value="option.id">{{option.name}}</option></select></div>'
|
149
|
+
},
|
107
150
|
boolean: {
|
108
151
|
props: ['label', 'value', 'options', 'description', 'shrink'],
|
109
152
|
template: '<div><mip-label :id="id" :label="label" :description="description" :hide_description="shrink"></mip-label> <a href="#" v-on:click.prevent.stop="shrink=false" v-show="shrink && !value">[^]</a><select :name="id" v-if="(value != undefined && value != null && value != \\'\\') || !shrink" v-on:input="$emit(\\'update:value\\', $event.target.value)"><option v-for="option in [true, false]" v-bind:value="option" :selected="value == option">{{option}}</option></select></div>'
|
@@ -147,7 +190,7 @@ module Mushy
|
|
147
190
|
},
|
148
191
|
button: {
|
149
192
|
props: ['click', 'description', 'name'],
|
150
|
-
template: '<button v-on:click.prevent.stop="click(pull(this))">{{name || id}}</button>'
|
193
|
+
template: '<button v-on:click.prevent.stop="click(pull(this), thisComponent())">{{name || id}}</button>'
|
151
194
|
}
|
152
195
|
};
|
153
196
|
|
@@ -167,6 +210,7 @@ module Mushy
|
|
167
210
|
return {
|
168
211
|
console: console,
|
169
212
|
pull: function(x) { return thingToData(foundIt.data); },
|
213
|
+
thisComponent: function() { return foundIt.data; },
|
170
214
|
}
|
171
215
|
},
|
172
216
|
props: props,
|
@@ -220,58 +264,89 @@ module Mushy
|
|
220
264
|
for(var type in fluxTypes)
|
221
265
|
options.push(fluxTypes[type]);
|
222
266
|
|
267
|
+
var saveTheFlux = function(input)
|
268
|
+
{
|
269
|
+
var theApp = input.app;
|
270
|
+
var config = input.config;
|
271
|
+
delete config.test_event;
|
272
|
+
var setup = thingToData(theApp.setup);
|
273
|
+
var flux = {
|
274
|
+
id: setup.id,
|
275
|
+
name: setup.name,
|
276
|
+
flux: setup.flux,
|
277
|
+
parents: setup.parents,
|
278
|
+
config: config,
|
279
|
+
};
|
280
|
+
var index = -1;
|
281
|
+
for(var i = 0; i < theApp.flow.fluxs.length; i++)
|
282
|
+
if (theApp.flow.fluxs[i].id == flux.id)
|
283
|
+
index = i;
|
284
|
+
|
285
|
+
if (index < 0)
|
286
|
+
theApp.flow.fluxs.push(flux);
|
287
|
+
else
|
288
|
+
theApp.flow.fluxs[index] = flux;
|
289
|
+
};
|
290
|
+
|
291
|
+
var saveTheFlow = function(input)
|
292
|
+
{
|
293
|
+
var setup = input.setup;
|
294
|
+
var flow = input.flow;
|
295
|
+
axios.post('/save', flow)
|
296
|
+
.then(function(result){});
|
297
|
+
};
|
298
|
+
|
299
|
+
var saveFlux = function(config) {
|
300
|
+
};
|
301
|
+
|
302
|
+
var ignoreFlux = function(config) {
|
303
|
+
};
|
304
|
+
|
223
305
|
var setup = {
|
224
306
|
showFlux: false,
|
225
307
|
id: { type: 'hide', value: '' },
|
226
308
|
name: { type: 'text', value: '' },
|
227
309
|
flux: { type: 'select', value: fluxdata.fluxs[0].name, options: options},
|
228
|
-
|
310
|
+
parents: { type: 'selectmanyrecords', label: 'Receive Events From', value: '', options: flowdata.fluxs },
|
229
311
|
};
|
230
312
|
|
231
313
|
for (var key in configs)
|
232
314
|
{
|
233
|
-
configs[key].save = { type: 'button', name: 'Save
|
234
|
-
|
235
|
-
|
236
|
-
|
237
|
-
|
238
|
-
|
239
|
-
|
240
|
-
|
241
|
-
|
242
|
-
var index = -1;
|
243
|
-
for(var i = 0; i < app.flow.fluxs.length; i++)
|
244
|
-
if (app.flow.fluxs[i].id == flux.id)
|
245
|
-
index = i;
|
246
|
-
if (index < 0)
|
247
|
-
app.flow.fluxs.push(flux);
|
248
|
-
else
|
249
|
-
app.flow.fluxs[index] = flux;
|
250
|
-
|
251
|
-
app.setup.id.value = '';
|
252
|
-
|
253
|
-
Vue.set(app.setup, 'showFlux', false);
|
254
|
-
}
|
315
|
+
configs[key].save = { type: 'button', name: 'Save Changes', click: function(config) {
|
316
|
+
saveTheFlux({ app: app, config: config });
|
317
|
+
saveTheFlow({ setup: app.setup, flow: app.flow });
|
318
|
+
app.setup.showFlux = false;
|
319
|
+
}
|
320
|
+
};
|
321
|
+
configs[key].cancel = { type: 'button', name: 'Ignore Changes', click: function() {
|
322
|
+
app.setup.showFlux = false;
|
323
|
+
}
|
255
324
|
};
|
256
325
|
|
257
326
|
configs[key].test_event = { type: 'json', value: '{}', default: '{}' };
|
258
327
|
|
259
|
-
configs[key].run_test = { type: 'button', name: 'Test Run This Flux', click: function(c) {
|
328
|
+
configs[key].run_test = { type: 'button', name: 'Test Run This Flux', click: function(c, hey) {
|
329
|
+
var previousName = hey.run_test.name;
|
330
|
+
Vue.set(hey.run_test, 'name', 'Loading');
|
260
331
|
app.results = [];
|
261
|
-
Vue.set(app.results, '
|
332
|
+
Vue.set(app.results, 'errorMessage', '');
|
262
333
|
var the_setup = thingToData(app.setup);
|
263
334
|
the_setup.event = c.test_event;
|
264
335
|
axios.post('/run', { config: c, setup: the_setup })
|
265
336
|
.then(function(r){
|
266
|
-
Vue.set(app.results, 'loading', false);
|
267
337
|
var index = 1;
|
268
338
|
for (var key in r.data.result)
|
269
339
|
{
|
270
340
|
var result = {};
|
271
|
-
result['event_' + index] = { type: 'jsonview', value: r.data.result[key], view: 'thin' };
|
341
|
+
result['event_' + index] = { type: 'jsonview', label: 'Event ' + index + ' of ' + r.data.result.length, value: r.data.result[key], view: 'thin' };
|
272
342
|
app.results.push(result);
|
273
343
|
index += 1;
|
274
344
|
}
|
345
|
+
}).catch(function(r){
|
346
|
+
console.log(r);
|
347
|
+
Vue.set(app.results, 'errorMessage', 'This app failed while trying to execute your flux.');
|
348
|
+
}).then(function(){
|
349
|
+
Vue.set(hey.run_test, 'name', previousName);
|
275
350
|
});
|
276
351
|
} };
|
277
352
|
}
|
@@ -285,7 +360,7 @@ module Mushy
|
|
285
360
|
Vue.set(setup.id, 'value', flux.id);
|
286
361
|
Vue.set(setup.name, 'value', flux.name);
|
287
362
|
Vue.set(setup.flux, 'value', flux.flux);
|
288
|
-
Vue.set(setup.
|
363
|
+
Vue.set(setup.parents, 'value', flux.parents);
|
289
364
|
|
290
365
|
var applicable_config = configs[flux.flux];
|
291
366
|
for(var key in applicable_config)
|
@@ -294,10 +369,12 @@ module Mushy
|
|
294
369
|
else
|
295
370
|
Vue.set(applicable_config[key], 'value', applicable_config[key].default);
|
296
371
|
|
372
|
+
if (applicable_config)
|
373
|
+
Vue.set(applicable_config.test_event, 'value', '{}');
|
297
374
|
|
298
375
|
options = flowdata.fluxs.filter(function(x){ return x.id != flux.id });
|
299
376
|
options.unshift( { id: '', name: '' } );
|
300
|
-
setup.
|
377
|
+
setup.parents.options = options;
|
301
378
|
|
302
379
|
Vue.set(setup, 'showFlux', true);
|
303
380
|
app.results = [];
|
@@ -317,15 +394,20 @@ module Mushy
|
|
317
394
|
flux = {
|
318
395
|
id: uuidv4(),
|
319
396
|
name: '',
|
397
|
+
parents: [],
|
320
398
|
config: {}
|
321
399
|
};
|
322
400
|
loadThisFlux({ flux: flux, setup: x.setup, configs: x.configs });
|
323
401
|
},
|
324
|
-
|
402
|
+
editFlux: function(x) {
|
325
403
|
var flux = x.flux;
|
326
404
|
|
327
405
|
loadThisFlux({ flux: x.flux, setup: x.setup, configs: x.configs });
|
328
406
|
},
|
407
|
+
deleteFlux: function(x) {
|
408
|
+
var set = x.flow.fluxs.filter( function(v){ return v.id != x.flux.id } );
|
409
|
+
Vue.set(x.flow, 'fluxs', set);
|
410
|
+
},
|
329
411
|
saveFlow: function(input)
|
330
412
|
{
|
331
413
|
var setup = input.setup;
|
@@ -337,9 +419,9 @@ module Mushy
|
|
337
419
|
},
|
338
420
|
configs: configs,
|
339
421
|
setup: setup,
|
340
|
-
flux_name_for: function(
|
341
|
-
var
|
342
|
-
return
|
422
|
+
flux_name_for: function(ids, fluxes) {
|
423
|
+
var fluxs = fluxes.filter(function(x){ return ids.includes(x.id) });
|
424
|
+
return fluxs.map(function(x){ return x.name }).join(', ');
|
343
425
|
},
|
344
426
|
results: [],
|
345
427
|
}
|
data/lib/mushy/flow.rb
CHANGED
@@ -18,8 +18,10 @@ module Mushy
|
|
18
18
|
end
|
19
19
|
|
20
20
|
def self.build_flux record
|
21
|
-
|
21
|
+
type = record[:type] || record['type'] || record[:flux] || record['flux'] || 'Flux'
|
22
|
+
flux = Object.const_get("Mushy::#{type}").new
|
22
23
|
flux.id = record[:id] || record['id'] || flux.id
|
24
|
+
flux.type = type
|
23
25
|
flux.config = SymbolizedHash.new(record[:config] || record['config'])
|
24
26
|
flux
|
25
27
|
end
|
data/lib/mushy/flux.rb
CHANGED
data/lib/mushy/fluxs/browser.rb
CHANGED
@@ -17,11 +17,19 @@ module Mushy
|
|
17
17
|
headless: {
|
18
18
|
description: 'Run this browser headless.',
|
19
19
|
type: 'boolean',
|
20
|
+
shrink: true,
|
20
21
|
value: 'true',
|
21
22
|
},
|
23
|
+
timeout: {
|
24
|
+
description: 'The default timeout (in seconds) before closing the browser. Default is 5 seconds.',
|
25
|
+
type: 'integer',
|
26
|
+
shrink: true,
|
27
|
+
value: '',
|
28
|
+
},
|
22
29
|
execute: {
|
23
30
|
description: 'Javascript to run after the page is loaded.',
|
24
31
|
type: 'textarea',
|
32
|
+
shrink: true,
|
25
33
|
value: '',
|
26
34
|
},
|
27
35
|
cookies: {
|
@@ -41,26 +49,29 @@ module Mushy
|
|
41
49
|
{ id: 'sameSite', target: 'sameSite', field: { type: 'text', value: 'None', default: 'None' } },
|
42
50
|
{ id: 'priority', target: 'priority', field: { type: 'text', value: 'Medium', default: 'Medium' } },
|
43
51
|
],
|
44
|
-
#{"name":"1P_JAR","value":"2021-01-21-13","domain":".google.com","path":"/","expires":1613828458.870408,"size":19,"httpOnly":false,"secure":true,"session":false,"sameSite":"None","priority":"Medium"
|
45
52
|
},
|
46
53
|
carry_cookies_from: {
|
47
54
|
description: 'Carry the cookies from this path in the event.',
|
48
55
|
type: 'text',
|
56
|
+
shrink: true,
|
49
57
|
value: 'cookies',
|
50
58
|
},
|
51
59
|
headers: {
|
52
60
|
description: 'Headers for the web request. These can be received from a previous browser event with {{headers}}, or can be typed manually.',
|
53
61
|
type: 'keyvalue',
|
62
|
+
shrink: true,
|
54
63
|
value: {},
|
55
64
|
},
|
56
65
|
carry_headers_from: {
|
57
66
|
description: 'Carry the headers from this path in the event.',
|
58
67
|
type: 'text',
|
68
|
+
shrink: true,
|
59
69
|
value: 'headers',
|
60
70
|
},
|
61
71
|
wait_before_closing: {
|
62
72
|
description: 'Wait this many seconds before closing the browser.',
|
63
73
|
type: 'integer',
|
74
|
+
shrink: true,
|
64
75
|
value: '',
|
65
76
|
},
|
66
77
|
},
|
@@ -69,7 +80,11 @@ module Mushy
|
|
69
80
|
|
70
81
|
def process event, config
|
71
82
|
|
72
|
-
|
83
|
+
timeout = config[:timeout] ? config[:timeout].to_i : 5
|
84
|
+
|
85
|
+
browser = Ferrum::Browser.new(
|
86
|
+
headless: (config[:headless].to_s != 'false'),
|
87
|
+
timeout: timeout)
|
73
88
|
|
74
89
|
get_the_cookies_from(event, config).each { |c| browser.cookies.set(c) }
|
75
90
|
|
@@ -79,20 +94,28 @@ module Mushy
|
|
79
94
|
|
80
95
|
browser.execute(config[:execute]) if config[:execute]
|
81
96
|
|
97
|
+
sleep(config[:wait_before_closing].to_i) if config[:wait_before_closing] && config[:wait_before_closing].to_i > 0
|
98
|
+
|
82
99
|
result = {
|
83
100
|
url: browser.url,
|
101
|
+
status: browser.network.status,
|
102
|
+
title: browser.frames[0].title,
|
84
103
|
cookies: browser.cookies.all.map { |k, v| v.instance_variable_get('@attributes') },
|
85
104
|
headers: browser.headers.get,
|
86
105
|
body: browser.body
|
87
106
|
}
|
88
107
|
|
89
|
-
|
108
|
+
result = special_browser_action browser, result
|
90
109
|
|
91
110
|
browser.quit
|
92
111
|
|
93
112
|
result
|
94
113
|
end
|
95
114
|
|
115
|
+
def special_browser_action browser, result
|
116
|
+
result
|
117
|
+
end
|
118
|
+
|
96
119
|
def get_the_cookies_from event, config
|
97
120
|
cookies = (event[config[:carry_cookies_from].to_sym])
|
98
121
|
cookies = [] unless cookies.is_a?(Array)
|
data/lib/mushy/fluxs/filter.rb
CHANGED
@@ -2,6 +2,29 @@ module Mushy
|
|
2
2
|
|
3
3
|
class Filter < Flux
|
4
4
|
|
5
|
+
def self.details
|
6
|
+
{
|
7
|
+
name: 'Filter',
|
8
|
+
description: 'Filters events based on criteria.',
|
9
|
+
config: {
|
10
|
+
equal: {
|
11
|
+
description: 'Provide key/value pairs that must match in the event.',
|
12
|
+
shrink: true,
|
13
|
+
label: 'Equal To',
|
14
|
+
type: 'keyvalue',
|
15
|
+
value: {},
|
16
|
+
},
|
17
|
+
notequal: {
|
18
|
+
description: 'Provide key/value pairs that must NOT match in the event.',
|
19
|
+
shrink: true,
|
20
|
+
label: 'Not Equal To',
|
21
|
+
type: 'keyvalue',
|
22
|
+
value: {},
|
23
|
+
},
|
24
|
+
},
|
25
|
+
}
|
26
|
+
end
|
27
|
+
|
5
28
|
def process event, config
|
6
29
|
|
7
30
|
differences = [:equal, :notequal]
|
@@ -0,0 +1,46 @@
|
|
1
|
+
module Mushy
|
2
|
+
|
3
|
+
class Screenshot < Browser
|
4
|
+
|
5
|
+
def self.details
|
6
|
+
details = Browser.details
|
7
|
+
details['name'] = 'Screenshot'
|
8
|
+
details['description'] = 'Take a screenshot of the browser.'
|
9
|
+
|
10
|
+
details[:config][:path] = {
|
11
|
+
description: 'The path of the file to save.',
|
12
|
+
type: 'text',
|
13
|
+
value: 'picture.jpg',
|
14
|
+
}
|
15
|
+
details[:config][:quality] = {
|
16
|
+
description: 'The quality of the image, a value beteen 0-100. Only applies to jpg.',
|
17
|
+
type: 'integer',
|
18
|
+
shrink: true,
|
19
|
+
value: '',
|
20
|
+
}
|
21
|
+
details[:config][:full] = {
|
22
|
+
description: 'Take a screenshot of the entire page. If false, the screenshot is limited to the viewport.',
|
23
|
+
type: 'boolean',
|
24
|
+
shrink: true,
|
25
|
+
value: '',
|
26
|
+
}
|
27
|
+
details
|
28
|
+
end
|
29
|
+
|
30
|
+
def special_browser_action browser, result
|
31
|
+
|
32
|
+
options = {
|
33
|
+
path: config[:path],
|
34
|
+
full: ['true', ''].include?(config[:full].to_s),
|
35
|
+
quality: (config[:quality].to_s == '' ? '100' : config[:quality]).to_i
|
36
|
+
}
|
37
|
+
|
38
|
+
browser.screenshot options
|
39
|
+
|
40
|
+
options
|
41
|
+
|
42
|
+
end
|
43
|
+
|
44
|
+
end
|
45
|
+
|
46
|
+
end
|
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
|
+
s.version = '0.2.1'
|
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.'
|
@@ -24,4 +24,4 @@ Gem::Specification.new do |s|
|
|
24
24
|
s.add_runtime_dependency 'ferrum'
|
25
25
|
s.add_runtime_dependency 'nokogiri'
|
26
26
|
s.add_runtime_dependency 'faraday'
|
27
|
-
end
|
27
|
+
end
|
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.
|
4
|
+
version: 0.2.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Darren Cauthon
|
@@ -142,6 +142,7 @@ files:
|
|
142
142
|
- lib/mushy/fluxs/bash.rb
|
143
143
|
- lib/mushy/fluxs/browser.rb
|
144
144
|
- lib/mushy/fluxs/build_csv.rb
|
145
|
+
- lib/mushy/fluxs/cli.rb
|
145
146
|
- lib/mushy/fluxs/collection.rb
|
146
147
|
- lib/mushy/fluxs/filter.rb
|
147
148
|
- lib/mushy/fluxs/format.rb
|
@@ -149,6 +150,7 @@ files:
|
|
149
150
|
- lib/mushy/fluxs/ls.rb
|
150
151
|
- lib/mushy/fluxs/parse_html.rb
|
151
152
|
- lib/mushy/fluxs/read_csv.rb
|
153
|
+
- lib/mushy/fluxs/screenshot.rb
|
152
154
|
- lib/mushy/fluxs/write_file.rb
|
153
155
|
- lib/mushy/masher.rb
|
154
156
|
- lib/mushy/run.rb
|