mushy 0.2.7 → 0.5.1

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: 92ba64469be678fe9889628ae7b6897f78935605605c83652d257f2c4a948d3d
4
- data.tar.gz: 1fa13be3acb6a38f8062536d416630f92867ed93b8f28ac3c140f91a6dfd1385
3
+ metadata.gz: 1768d2d862215f72ec4ac972490931ac8d989ed8b37353c2d90c440a47047519
4
+ data.tar.gz: 157ae813b2b0c616e574f8e4d15186c64347c86c3d76c67d18e2f12b71a9d550
5
5
  SHA512:
6
- metadata.gz: d9aaebd4c3a70c7e64417eb515d719ad6e0bd0c6ccacdde4a2b8ae21845e77b63ee2ca0639d1207aa2d064c8aa3bda48f282a3f640e07b26c171cd1819191416
7
- data.tar.gz: ba95b540eb1746ae7b525221c746aee163861c62956e3ac08e5405738bdf329eea32c0d8378283b6c625a1d1919d6f1fd11b936548822ce2a15c438651112a6f
6
+ metadata.gz: ea5cd34d6d16a19f80548831804278a6f7b958612c1fd72a1c8c4df71a9fad1cc1c0578ed9ed35e5afb90a860f4579f4317fb29d4592b38369b9dcc7ec6f6840
7
+ data.tar.gz: 4ecf0d5b933a45eff8d2a2f8d4c4f73bb932476d69cf6456d9c67ca20b46cae1f933a2898eaefa8b49e0e5f149b18a3443de322ba4fc73eb5bd98ae95ba3c8af
data/bin/mushy CHANGED
@@ -10,7 +10,8 @@ class MushyCLI < Thor
10
10
 
11
11
  desc "start FILE", "Run this workflow file."
12
12
  def start
13
- Mushy::Builder::Api.start file, values
13
+ v = values || {}
14
+ Mushy::Builder::Api.start file, v
14
15
  end
15
16
 
16
17
  desc "build FILE", 'Build a flow.'
@@ -1,3 +1,5 @@
1
+ require 'daemons'
2
+
1
3
  module Mushy
2
4
 
3
5
  module Builder
@@ -32,9 +34,34 @@ module Mushy
32
34
  file = "#{file}.json" unless file.downcase.end_with?('.json')
33
35
  flow = File.open(file).read
34
36
  flow = Mushy::Flow.parse flow
35
- flux = flow.fluxs.select { |x| x.type == 'Cli' }.first
36
37
 
37
- Mushy::Runner.new.start event, flux, flow
38
+ service_fluxes = flow.fluxs.select { |x| x.respond_to? :loop }
39
+
40
+ pwd = Dir.pwd
41
+
42
+ if service_fluxes.any?
43
+ calls = service_fluxes
44
+ .map { |s| { flux: s, proc: ->(e) do
45
+ Dir.chdir pwd
46
+ Mushy::Runner.new.start e, s, flow
47
+ end } }
48
+ .map { |p| ->() { p[:flux].loop &p[:proc] } }
49
+ .map { |x| ->() { loop &x } }
50
+ .map { |x| run_as_a_daemon &x }
51
+
52
+ puts calls.inspect
53
+
54
+ exit
55
+ end
56
+
57
+ cli_flux = flow.fluxs.select { |x| x.kind_of?(Mushy::Cli) }.first
58
+
59
+ Mushy::Runner.new.start event, cli_flux, flow
60
+ end
61
+
62
+ def self.run_as_a_daemon &block
63
+ #block.call
64
+ Daemons.call(&block).pid.pid
38
65
  end
39
66
 
40
67
  def self.get_flow file
@@ -68,6 +95,14 @@ module Mushy
68
95
  details[:config][:sort] = { type: 'text', shrink: true, description: 'Sort by this key.', default: '' }
69
96
  details[:config][:model] = { type: 'keyvalue', shrink: true, description: 'Reshape the outgoing events.', value: {}, default: {} }
70
97
 
98
+ details[:config][:error_strategy] = {
99
+ description: 'Error strategy. (return to return an event with "exception" returning the error, or ignore to ignore the exception)',
100
+ type: 'select',
101
+ options: ['', 'return', 'ignore'],
102
+ value: '',
103
+ shrink: true,
104
+ }
105
+
71
106
  details[:config]
72
107
  .select { |_, v| v[:type] == 'keyvalue' }
73
108
  .select { |_, v| v[:editors].nil? }
@@ -0,0 +1,30 @@
1
+ module Mushy
2
+
3
+ module DateParts
4
+
5
+ def self.parse now
6
+ {
7
+ year: nil,
8
+ month: nil,
9
+ day: nil,
10
+ hour: nil,
11
+ minute: :min,
12
+ second: :sec,
13
+ nanosecond: :nsec,
14
+ utc_offset: nil,
15
+ weekday: :wday,
16
+ day_of_month: :mday,
17
+ day_of_year: :yday,
18
+ string: :to_s,
19
+ epoch_integer: :to_i,
20
+ epoch_float: :to_f,
21
+ }.reduce({}) do |t, i|
22
+ method = i[1] || i[0]
23
+ t[i[0]] = now.send method
24
+ t
25
+ end
26
+ end
27
+
28
+ end
29
+
30
+ end
data/lib/mushy/flux.rb CHANGED
@@ -77,6 +77,10 @@ module Mushy
77
77
 
78
78
  returned_one_result ? results.first : results
79
79
 
80
+ rescue Exception => e
81
+ raise e if config[:error_strategy].to_s == ''
82
+ return [] if config[:error_strategy] == 'ignore'
83
+ { exception: e.message }
80
84
  end
81
85
 
82
86
  def standardize_these results
@@ -15,6 +15,7 @@ module Mushy
15
15
  directory: {
16
16
  description: 'The working directory in which the command will be run.',
17
17
  type: 'text',
18
+ shrink: true,
18
19
  value: '',
19
20
  },
20
21
  },
@@ -18,7 +18,7 @@ module Mushy
18
18
  description: 'Run this browser headless.',
19
19
  type: 'boolean',
20
20
  shrink: true,
21
- value: 'true',
21
+ value: '',
22
22
  },
23
23
  timeout: {
24
24
  description: 'The default timeout (in seconds) before closing the browser. Default is 5 seconds.',
@@ -90,7 +90,9 @@ module Mushy
90
90
 
91
91
  browser.headers.add get_the_headers_from(event, config)
92
92
 
93
+ the_start = Time.now
93
94
  browser.goto config[:url]
95
+ time = Time.now - the_start
94
96
 
95
97
  browser.execute(config[:execute]) if config[:execute]
96
98
 
@@ -102,6 +104,7 @@ module Mushy
102
104
  title: browser.frames[0].title,
103
105
  cookies: browser.cookies.all.map { |k, v| v.instance_variable_get('@attributes') },
104
106
  headers: browser.headers.get,
107
+ time: time,
105
108
  body: browser.body
106
109
  }
107
110
 
@@ -0,0 +1,27 @@
1
+ module Mushy
2
+
3
+ class Document < Flux
4
+
5
+ def self.details
6
+ {
7
+ name: 'Document',
8
+ description: 'Create a multi-line document.',
9
+ config: {
10
+ document: {
11
+ description: 'The multi-line document you wish to create.',
12
+ type: 'textarea',
13
+ value: '',
14
+ },
15
+ },
16
+ }
17
+ end
18
+
19
+ def process event, config
20
+ {
21
+ document: config[:document],
22
+ }
23
+ end
24
+
25
+ end
26
+
27
+ end
@@ -0,0 +1,56 @@
1
+ require 'csv'
2
+
3
+ module Mushy
4
+
5
+ class Interval < Flux
6
+
7
+ def self.setup
8
+ {
9
+ seconds: ->(x) { x },
10
+ minutes: ->(x) { x * 60 },
11
+ hours: ->(x) { x * 60 * 60 },
12
+ days: ->(x) { x * 60 * 60 * 24 },
13
+ weeks: ->(x) { x * 60 * 60 * 24 * 7 },
14
+ }
15
+ end
16
+
17
+ def self.details
18
+ {
19
+ name: 'Interval',
20
+ description: 'Fire an event every X minutes.',
21
+ config: {},
22
+ }.tap do |c|
23
+ setup.keys.each do |key|
24
+ c[:config][key] = {
25
+ description: "#{key.to_s.capitalize} until the job is fired again.",
26
+ type: 'integer',
27
+ shrink: true,
28
+ value: '',
29
+ }
30
+ end
31
+ end
32
+ end
33
+
34
+ def loop &block
35
+ event = { time: time }
36
+ block.call event
37
+ sleep time
38
+ end
39
+
40
+ def time
41
+ the_time = self.class.setup.keys
42
+ .select { |x| config[x].to_s != '' }
43
+ .map { |x| self.class.setup[x].call(config[x].to_i) }
44
+ .sum
45
+
46
+ the_time > 0 ? the_time : 60
47
+ end
48
+
49
+ def process event, config
50
+ now = Time.now
51
+ Mushy::DateParts.parse now
52
+ end
53
+
54
+ end
55
+
56
+ end
@@ -6,30 +6,133 @@ module Mushy
6
6
  {
7
7
  name: 'Ls',
8
8
  description: 'Run the "ls" command.',
9
- config: {
10
- directory: {
11
- description: 'The working directory in which the command will be run.',
12
- type: 'text',
13
- value: '',
14
- },
15
- },
16
- }
9
+ config: Mushy::Bash.details[:config].tap { |c| c.delete :command },
10
+ }.tap do |c|
11
+ c[:config][:recursive] = {
12
+ description: 'Pull files recursively.',
13
+ type: 'boolean',
14
+ shrink: true,
15
+ value: '',
16
+ }
17
+ c[:config][:path] = {
18
+ description: 'Path, used to search for specific files.',
19
+ type: 'text',
20
+ shrink: true,
21
+ value: '',
22
+ }
23
+ end
17
24
  end
18
25
 
19
26
  def process event, config
27
+ arguments = build_the_arguments_from config
20
28
 
21
- config[:command] = 'ls'
22
-
29
+ config[:command] = build_the_command_from arguments
23
30
  result = super event, config
24
31
 
25
- return result unless result[:success]
32
+ things = turn_the_ls_output_to_events result, config, event
33
+ things
34
+ end
35
+
36
+ def build_the_command_from arguments
37
+ "ls #{arguments.join(' ')}"
38
+ end
39
+
40
+ def build_the_arguments_from config
41
+ arguments = ['-A', '-l', '--full-time', '-i']
42
+ arguments << '-R' if config[:recursive].to_s == 'true'
43
+ arguments << '-d' if config[:directory_only].to_s == 'true'
44
+ arguments << config[:path] if config[:path].to_s != ''
45
+ arguments
46
+ end
47
+
48
+ def turn_the_ls_output_to_events result, config, event
49
+
50
+ lines = result[:text].split("\n")
51
+
52
+ needs_special_work_for_path = config[:directory_only].to_s != 'true' &&
53
+ config[:path].to_s != '' &&
54
+ lines[0].start_with?('total ')
55
+
56
+ origin = config[:directory] || Dir.pwd
57
+ directory = needs_special_work_for_path ? '||DIRECTORY||' : origin
58
+
59
+ things = lines.map do |x|
60
+ segments = x.split ' '
61
+ result = if segments.count > 5
62
+ pull_file segments, directory
63
+ elsif segments.count == 1
64
+ dir_segments = segments[0].split("\/")
65
+
66
+ if dir_segments[0] == '.'
67
+ dir_segments[0] = origin
68
+ else
69
+ dir_segments.unshift origin
70
+ end
71
+
72
+ dir_segments[-1] = dir_segments[-1].sub ':', ''
73
+ directory = dir_segments.join("\/")
74
+ nil
75
+ else
76
+ nil
77
+ end
78
+ end.select { |x| x }
79
+
80
+ if needs_special_work_for_path
81
+ config[:directory_only] = true
82
+ special_name = process(event, config)[0][:name]
83
+ things.each do |x|
84
+ [:directory, :path].each do |key|
85
+ if x[key].include?('||DIRECTORY||')
86
+ x[key].sub!('||DIRECTORY||', File.join(Dir.pwd, special_name))
87
+ end
88
+ end
89
+ end
90
+ end
91
+
92
+ things
93
+ end
94
+
95
+ def pull_file segments, directory
96
+ result = {}
97
+
98
+ [:inode, :help, :hard_links, :owner, :group, :size].each do |key|
99
+ result[key] = segments.shift; x = segments.join ' '
100
+ end
101
+
102
+ result.tap do |r|
103
+ r[:date] = []
104
+ 3.times { r[:date] << segments.shift }
105
+ r[:date] = r[:date].join ' '
106
+ r[:date] = Time.parse r[:date]
107
+ end
108
+
109
+ result[:name] = segments.shift
110
+
111
+ result.tap do |r|
112
+ help_segments = r[:help].split ''
113
+ r[:type] = help_segments[0]
114
+ r[:owner_permission] = [1, 2, 3].map { |i| help_segments[i] }.reduce('') { |t, i| t + i }
115
+ r[:group_permission] = [4, 5, 6].map { |i| help_segments[i] }.reduce('') { |t, i| t + i }
116
+ r[:other_permission] = [7, 8, 9].map { |i| help_segments[i] }.reduce('') { |t, i| t + i }
117
+ r.delete :help
118
+ end
119
+
120
+ [:hard_links, :size].each { |x| result[x] = result[x].to_i }
121
+
122
+ result[:date] = Mushy::DateParts.parse result[:date]
123
+
124
+ result[:directory] = directory
26
125
 
27
- result[:text].split("\n").map do |x|
28
- {
29
- name: x,
30
- }
126
+ if result[:type] == 'd' && result[:directory] == result[:name]
127
+ result[:path] = result[:directory]
128
+ name_segments = result[:name].split "\/"
129
+ result[:name] = name_segments.pop
130
+ result[:directory] = name_segments.join "\/"
131
+ else
132
+ result[:path] = File.join result[:directory], result[:name]
31
133
  end
32
134
 
135
+ result
33
136
  end
34
137
 
35
138
  end
@@ -0,0 +1,26 @@
1
+ module Mushy
2
+
3
+ class Print < Flux
4
+
5
+ def self.details
6
+ {
7
+ name: 'Print',
8
+ description: 'Print output to the screen.',
9
+ config: {
10
+ message: {
11
+ description: 'The message to display',
12
+ type: 'text',
13
+ value: '',
14
+ },
15
+ }
16
+ }
17
+ end
18
+
19
+ def process event, config
20
+ puts config[:message]
21
+ {}
22
+ end
23
+
24
+ end
25
+
26
+ end
@@ -0,0 +1,31 @@
1
+ module Mushy
2
+
3
+ class Pwd < Bash
4
+
5
+ def self.details
6
+ {
7
+ name: 'Pwd',
8
+ description: 'Run the "pwd" command.',
9
+ config: Mushy::Bash.details[:config].tap { |c| c.delete :command },
10
+ }
11
+ end
12
+
13
+ def process event, config
14
+
15
+ config[:command] = 'pwd'
16
+
17
+ result = super event, config
18
+
19
+ return result unless result[:success]
20
+
21
+ pwd = result[:text].to_s.strip
22
+
23
+ {
24
+ pwd: Mushy::Ls.new.process({}, { path: pwd, directory_only: true })[0]
25
+ }
26
+
27
+ end
28
+
29
+ end
30
+
31
+ end
@@ -7,11 +7,10 @@ module Mushy
7
7
  details['name'] = 'Screenshot'
8
8
  details['description'] = 'Take a screenshot of the browser.'
9
9
 
10
- details[:config][:path] = {
11
- description: 'The path of the file to save.',
12
- type: 'text',
13
- value: 'picture.jpg',
14
- }
10
+ details[:config].merge!(Mushy::WriteFile.file_saving_config.tap do |x|
11
+ x[x.keys.first][:value] = 'file.jpg'
12
+ end)
13
+
15
14
  details[:config][:quality] = {
16
15
  description: 'The quality of the image, a value beteen 0-100. Only applies to jpg.',
17
16
  type: 'integer',
@@ -33,15 +32,19 @@ module Mushy
33
32
  the_result = input[:result]
34
33
  the_config = input[:config]
35
34
 
35
+ file = Mushy::WriteFile.get_file_from the_config
36
36
  options = {
37
- path: the_config[:path],
37
+ path: file,
38
38
  full: ['true', ''].include?(the_config[:full].to_s),
39
39
  quality: (the_config[:quality].to_s == '' ? '100' : the_config[:quality]).to_i
40
40
  }
41
41
 
42
42
  the_browser.screenshot options
43
43
 
44
- options
44
+ the_result[:options] = options
45
+ the_result[:file] = Mushy::Ls.new.process({}, { path: file })[0]
46
+
47
+ the_result
45
48
 
46
49
  end
47
50
 
@@ -6,34 +6,46 @@ module Mushy
6
6
  {
7
7
  name: 'WriteFile',
8
8
  description: 'Write a file.',
9
- config: {
10
- name: {
11
- description: 'The name of the file.',
12
- type: 'text',
13
- value: 'file.csv',
14
- },
15
- directory: {
16
- description: 'The directory in which to write the file. Leave blank for the current directory.',
17
- type: 'text',
18
- value: '',
19
- },
20
- data: {
21
- description: 'The text to write. You can use Liquid templating here to pull data from the event, or write hardcoded data.',
22
- type: 'text',
23
- value: '{{data}}',
24
- },
25
- },
9
+ config: file_saving_config.merge({
10
+ data: {
11
+ description: 'The text to write. You can use Liquid templating here to pull data from the event, or write hardcoded data.',
12
+ type: 'text',
13
+ value: '{{data}}',
14
+ },
15
+ }),
26
16
  }
27
17
  end
28
18
 
29
- def process event, config
30
- file = config[:name]
19
+ def self.file_saving_config
20
+ {
21
+ name: {
22
+ description: 'The name of the file.',
23
+ type: 'text',
24
+ value: 'file.csv',
25
+ },
26
+ directory: {
27
+ description: 'The directory in which to write the file. Leave blank for the current directory.',
28
+ shrink: true,
29
+ type: 'text',
30
+ value: '',
31
+ },
32
+ }
33
+ end
31
34
 
35
+ def self.get_file_from config
36
+ file = config[:name]
32
37
  file = File.join(config[:directory], file) if config[:directory].to_s != ''
38
+ file
39
+ end
40
+
41
+ def process event, config
42
+ file = self.class.get_file_from config
33
43
 
34
44
  File.open(file, 'w') { |f| f.write config[:data] }
35
45
 
36
- {}
46
+ {
47
+ file: Mushy::Ls.new.process({}, { path: file })[0]
48
+ }
37
49
  end
38
50
 
39
51
  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.2.7'
7
+ s.version = '0.5.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.'
@@ -25,4 +25,5 @@ Gem::Specification.new do |s|
25
25
  s.add_runtime_dependency 'nokogiri'
26
26
  s.add_runtime_dependency 'faraday'
27
27
  s.add_runtime_dependency 'pony'
28
+ s.add_runtime_dependency 'daemons'
28
29
  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.2.7
4
+ version: 0.5.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Darren Cauthon
@@ -136,6 +136,20 @@ dependencies:
136
136
  - - ">="
137
137
  - !ruby/object:Gem::Version
138
138
  version: '0'
139
+ - !ruby/object:Gem::Dependency
140
+ name: daemons
141
+ requirement: !ruby/object:Gem::Requirement
142
+ requirements:
143
+ - - ">="
144
+ - !ruby/object:Gem::Version
145
+ version: '0'
146
+ type: :runtime
147
+ prerelease: false
148
+ version_requirements: !ruby/object:Gem::Requirement
149
+ requirements:
150
+ - - ">="
151
+ - !ruby/object:Gem::Version
152
+ version: '0'
139
153
  description: This tool assists in the creation and processing of workflows.
140
154
  email: darren@cauthon.com
141
155
  executables:
@@ -150,6 +164,7 @@ files:
150
164
  - lib/mushy/builder/dark.rb
151
165
  - lib/mushy/builder/index.rb
152
166
  - lib/mushy/builder/vue.rb
167
+ - lib/mushy/date_parts.rb
153
168
  - lib/mushy/event.rb
154
169
  - lib/mushy/flow.rb
155
170
  - lib/mushy/flux.rb
@@ -158,14 +173,18 @@ files:
158
173
  - lib/mushy/fluxs/build_csv.rb
159
174
  - lib/mushy/fluxs/cli.rb
160
175
  - lib/mushy/fluxs/collection.rb
176
+ - lib/mushy/fluxs/document.rb
161
177
  - lib/mushy/fluxs/environment.rb
162
178
  - lib/mushy/fluxs/filter.rb
163
179
  - lib/mushy/fluxs/format.rb
164
180
  - lib/mushy/fluxs/get.rb
165
181
  - lib/mushy/fluxs/git_log.rb
182
+ - lib/mushy/fluxs/interval.rb
166
183
  - lib/mushy/fluxs/ls.rb
167
184
  - lib/mushy/fluxs/parse_html.rb
168
185
  - lib/mushy/fluxs/pdf.rb
186
+ - lib/mushy/fluxs/print.rb
187
+ - lib/mushy/fluxs/pwd.rb
169
188
  - lib/mushy/fluxs/read_csv.rb
170
189
  - lib/mushy/fluxs/read_file.rb
171
190
  - lib/mushy/fluxs/screenshot.rb