mushy 0.2.4 → 0.4.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: 1dffff192ce9f7784515f5b4c73a1ac15720cc2e8cb5a6a5836b34dd5049eb52
4
- data.tar.gz: 247eeecec22765e28eb98e850982e8ef06ec3e969257da56e0923baadc237b9d
3
+ metadata.gz: 7fdb340186745a43f2930f3b0e60a6538076593f3cb8cf3464fba209ac90d409
4
+ data.tar.gz: cbe1b085e5844c4facabd43d5451f6f34b0fc21cba4909460028dd5bab007c5f
5
5
  SHA512:
6
- metadata.gz: 1a85f196c4c86ad29b3a96d90356cd74264a443cdfaf58a4662a407f4ef01bb2cb7cbd1098f3a20c57a2d3f901160b5ddbf309f6c6d03fcc8d1c691ba08ed9d7
7
- data.tar.gz: 386d48b9ba0aaa610dca7675f780ab186aedf15ae14b3a31e41c119d5e427b0bcd1f58b7f17d6395b6e6625cbdcd328861512507b14bbc3b5681648f1382ac4a
6
+ metadata.gz: 85af2b856ca023cef5a65fba574b615683b9898c20aea0a87f3aa24c2061382ebfb14eb9a7aee40e6267c7cb34666c12f8c1c939f3a4207a8a7fc90c6114817b
7
+ data.tar.gz: 7f21edc8cd3e5f256dc038e16569a402f4d104a81060e08601b65afd325e7c71f2d22e5bdf39b895121034a8551025cbf7db9da62a6d4af1d2724d1ee706247f
@@ -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
@@ -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
@@ -0,0 +1,28 @@
1
+ module Mushy
2
+
3
+ class Environment < Flux
4
+
5
+ def self.details
6
+ {
7
+ name: 'Environment',
8
+ description: 'Pull environment variables.',
9
+ config: {
10
+ variables: {
11
+ description: 'Map the environment variables to a new event.',
12
+ type: 'keyvalue',
13
+ value: {},
14
+ },
15
+ },
16
+ }
17
+ end
18
+
19
+ def process event, config
20
+ config[:variables].reduce({}) do |t, i|
21
+ t[i[0]] = ENV[i[1]]
22
+ t
23
+ end
24
+ end
25
+
26
+ end
27
+
28
+ end
@@ -0,0 +1,86 @@
1
+ module Mushy
2
+
3
+ class GitLog < Bash
4
+
5
+ def self.details
6
+ {
7
+ name: 'GitLog',
8
+ description: 'Return git logs.',
9
+ config: {
10
+ directory: {
11
+ description: 'The working directory in which the command will be run.',
12
+ type: 'text',
13
+ shrink: true,
14
+ value: '',
15
+ },
16
+ after: {
17
+ description: 'Filter for commits after this',
18
+ type: 'text',
19
+ shrink: true,
20
+ value: '',
21
+ },
22
+ before: {
23
+ description: 'Filter for commits before this',
24
+ type: 'text',
25
+ shrink: true,
26
+ value: '',
27
+ },
28
+ author: {
29
+ description: 'Filter for commits by this author',
30
+ type: 'text',
31
+ shrink: true,
32
+ value: '',
33
+ },
34
+ committer: {
35
+ description: 'Filter for commits by this committer',
36
+ type: 'text',
37
+ shrink: true,
38
+ value: '',
39
+ },
40
+ },
41
+ }
42
+ end
43
+
44
+ def process event, config
45
+
46
+ config[:command] = 'git log'
47
+
48
+ if config[:directory].to_s != ''
49
+ config[:command] = "cd \"#{config[:directory]}\";#{config[:command]}"
50
+ end
51
+
52
+ [:after, :before, :author, :committer]
53
+ .select { |x| config[x].to_s != ''}
54
+ .each { |k| config[:command] = "#{config[:command]} --#{k}=\"#{config[k]}\"" }
55
+
56
+ result = super event, config
57
+
58
+ return result unless result[:success]
59
+
60
+ result[:text].split("\n\n").reduce([]) do |results, line|
61
+ if line.start_with? 'commit'
62
+ results << { message: line.sub('commit', 'commit:') }
63
+ else
64
+ results[-1][:message] = results[-1][:message] + "\nMessage: " + line.strip
65
+ end
66
+ results
67
+ end.map { |x| x[:message] }.map do |line|
68
+ line.split("\n").reduce({}) do |t, i|
69
+ segments = i.split ':'
70
+ key = segments.shift.strip.downcase.to_sym
71
+ t[key] = segments.map { |y| y.strip }.join ':'
72
+ t
73
+ end
74
+ end.map do |commit|
75
+ commit.tap do |x|
76
+ segments = x[:author].split '<'
77
+ x[:author_name] = segments.shift.strip
78
+ x[:author_email] = segments.join('').strip.gsub('>', '')
79
+ end
80
+ end
81
+
82
+ end
83
+
84
+ end
85
+
86
+ 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,82 @@ 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
+ end
17
18
  end
18
19
 
19
20
  def process event, config
20
21
 
21
- config[:command] = 'ls'
22
+ arguments = ['-A', '-l', '--full-time', '-i']
23
+ arguments << '-R' if config[:recursive].to_s == 'true'
24
+ config[:command] = "ls #{arguments.join(' ')}"
22
25
 
23
26
  result = super event, config
24
27
 
25
28
  return result unless result[:success]
26
29
 
27
- result[:text].split("\n").map do |x|
28
- {
29
- name: x,
30
- }
30
+ lines = result[:text].split("\n")
31
+ lines.shift
32
+
33
+ origin = config[:directory] || Dir.pwd
34
+ directory = origin
35
+ lines.map do |x|
36
+ segments = x.split ' '
37
+ result = if segments.count > 5
38
+ pull_file segments, directory
39
+ elsif segments.count == 1
40
+ dir_segments = segments[0].split("\/")
41
+ dir_segments[0] = origin if dir_segments[0] == '.'
42
+ dir_segments[-1] = dir_segments[-1].sub ':', ''
43
+ directory = dir_segments.join("\/")
44
+ nil
45
+ else
46
+ nil
47
+ end
48
+ end.select { |x| x }
49
+
50
+ end
51
+
52
+ def pull_file segments, directory
53
+ result = {}
54
+
55
+ [:inode, :help, :hard_links, :owner, :group, :size].each do |key|
56
+ result[key] = segments.shift; x = segments.join ' '
57
+ end
58
+
59
+ result.tap do |r|
60
+ r[:date] = []
61
+ 3.times { r[:date] << segments.shift }
62
+ r[:date] = r[:date].join ' '
63
+ r[:date] = Time.parse r[:date]
64
+ end
65
+
66
+ result[:name] = segments.shift
67
+
68
+ result.tap do |r|
69
+ help_segments = r[:help].split ''
70
+ r[:type] = help_segments[0]
71
+ r[:owner_permission] = [1, 2, 3].map { |i| help_segments[i] }.reduce('') { |t, i| t + i }
72
+ r[:group_permission] = [4, 5, 6].map { |i| help_segments[i] }.reduce('') { |t, i| t + i }
73
+ r[:other_permission] = [7, 8, 9].map { |i| help_segments[i] }.reduce('') { |t, i| t + i }
74
+ r.delete :help
31
75
  end
32
76
 
77
+ [:hard_links, :size].each { |x| result[x] = result[x].to_i }
78
+
79
+ result[:date_parts] = Mushy::DateParts.parse result[:date]
80
+
81
+ result[:directory] = directory
82
+ result[:path] = File.join result[:directory], result[:name]
83
+
84
+ result
33
85
  end
34
86
 
35
87
  end
@@ -0,0 +1,46 @@
1
+ module Mushy
2
+
3
+ class Pdf < Browser
4
+
5
+ def self.details
6
+ details = Browser.details
7
+ details['name'] = 'Pdf'
8
+ details['description'] = 'Turn a URL into a PDF.'
9
+
10
+ details[:config][:path] = {
11
+ description: 'The path of the PDF file to save.',
12
+ type: 'text',
13
+ value: 'picture.pdf',
14
+ }
15
+
16
+ details[:config][:landscape] = {
17
+ description: 'Build the PDF in landscape. Defaults to false.',
18
+ type: 'boolean',
19
+ shrink: true,
20
+ value: '',
21
+ }
22
+
23
+ details
24
+ end
25
+
26
+ def adjust input
27
+
28
+ the_browser = input[:browser]
29
+ the_result = input[:result]
30
+ the_config = input[:config]
31
+
32
+ options = {
33
+ path: the_config[:path],
34
+ }
35
+
36
+ options[:landscape] = true if the_config[:landscape].to_s == 'true'
37
+
38
+ the_browser.pdf options
39
+
40
+ options
41
+
42
+ end
43
+
44
+ end
45
+
46
+ 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,29 @@
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
+ {
22
+ pwd: result[:text].to_s.strip
23
+ }
24
+
25
+ end
26
+
27
+ end
28
+
29
+ end
@@ -0,0 +1,115 @@
1
+ require 'pony'
2
+
3
+ module Mushy
4
+
5
+ class Smtp < Flux
6
+
7
+ def self.details
8
+ {
9
+ name: 'Smtp',
10
+ description: 'Send email through SMTP.',
11
+ config: {
12
+ from: {
13
+ description: 'From whom the email will be sent.',
14
+ type: 'text',
15
+ shrink: true,
16
+ value: '',
17
+ },
18
+ to: {
19
+ description: 'To whom the email should be sent.',
20
+ type: 'text',
21
+ value: '',
22
+ },
23
+ subject: {
24
+ description: 'The subject of the email.',
25
+ type: 'text',
26
+ value: '',
27
+ },
28
+ body: {
29
+ description: 'The text body of the email.',
30
+ type: 'textarea',
31
+ value: '',
32
+ },
33
+ html_body: {
34
+ description: 'The HTML body of the email.',
35
+ type: 'textarea',
36
+ value: '',
37
+ },
38
+ attachment_file: {
39
+ description: 'The full path of a file to attach.',
40
+ type: 'text',
41
+ shrink: true,
42
+ value: '',
43
+ },
44
+ address: {
45
+ description: 'The address of the SMTP server.',
46
+ type: 'text',
47
+ value: 'smtp.gmail.com',
48
+ },
49
+ port: {
50
+ description: 'The SMTP server port.',
51
+ type: 'integer',
52
+ value: '587',
53
+ },
54
+ domain: {
55
+ description: 'The email domain.',
56
+ type: 'text',
57
+ value: 'gmail.com',
58
+ },
59
+ username: {
60
+ description: 'The username.',
61
+ type: 'text',
62
+ value: '',
63
+ },
64
+ password: {
65
+ description: 'The password.',
66
+ type: 'text',
67
+ value: '',
68
+ },
69
+ },
70
+ }
71
+ end
72
+
73
+ def process event, config
74
+ options = adjust(cleanup({
75
+ from: config[:from],
76
+ to: config[:to],
77
+ subject: config[:subject],
78
+ body: config[:body],
79
+ html_body: config[:html_body],
80
+ via_options: get_via_options_from(config)
81
+ }))
82
+
83
+ if (config[:attachment_file].to_s != '')
84
+ options[:attachments] = { config[:attachment_file].split("\/")[-1] => File.read(config[:attachment_file]) }
85
+ end
86
+
87
+ result = Pony.mail options
88
+ options.tap { |x| x.delete(:via_options) }
89
+ end
90
+
91
+ def adjust options
92
+ options.tap { |x| x[:via] = 'smtp' }
93
+ end
94
+
95
+ def cleanup options
96
+ options.tap do |hash|
97
+ hash.delete_if { |_, v| v.to_s == '' }
98
+ end
99
+ end
100
+
101
+ def get_via_options_from config
102
+ {
103
+ address: config[:address],
104
+ port: config[:port].to_s,
105
+ user_name: config[:username],
106
+ password: config[:password],
107
+ domain: config[:domain],
108
+ authentication: :plain,
109
+ enable_starttls_auto: true,
110
+ }
111
+ end
112
+
113
+ end
114
+
115
+ 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.4'
7
+ s.version = '0.4.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.'
@@ -24,4 +24,6 @@ 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
+ s.add_runtime_dependency 'pony'
28
+ s.add_runtime_dependency 'daemons'
27
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.4
4
+ version: 0.4.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Darren Cauthon
@@ -122,6 +122,34 @@ dependencies:
122
122
  - - ">="
123
123
  - !ruby/object:Gem::Version
124
124
  version: '0'
125
+ - !ruby/object:Gem::Dependency
126
+ name: pony
127
+ requirement: !ruby/object:Gem::Requirement
128
+ requirements:
129
+ - - ">="
130
+ - !ruby/object:Gem::Version
131
+ version: '0'
132
+ type: :runtime
133
+ prerelease: false
134
+ version_requirements: !ruby/object:Gem::Requirement
135
+ requirements:
136
+ - - ">="
137
+ - !ruby/object:Gem::Version
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'
125
153
  description: This tool assists in the creation and processing of workflows.
126
154
  email: darren@cauthon.com
127
155
  executables:
@@ -136,6 +164,7 @@ files:
136
164
  - lib/mushy/builder/dark.rb
137
165
  - lib/mushy/builder/index.rb
138
166
  - lib/mushy/builder/vue.rb
167
+ - lib/mushy/date_parts.rb
139
168
  - lib/mushy/event.rb
140
169
  - lib/mushy/flow.rb
141
170
  - lib/mushy/flux.rb
@@ -144,14 +173,21 @@ files:
144
173
  - lib/mushy/fluxs/build_csv.rb
145
174
  - lib/mushy/fluxs/cli.rb
146
175
  - lib/mushy/fluxs/collection.rb
176
+ - lib/mushy/fluxs/environment.rb
147
177
  - lib/mushy/fluxs/filter.rb
148
178
  - lib/mushy/fluxs/format.rb
149
179
  - lib/mushy/fluxs/get.rb
180
+ - lib/mushy/fluxs/git_log.rb
181
+ - lib/mushy/fluxs/interval.rb
150
182
  - lib/mushy/fluxs/ls.rb
151
183
  - lib/mushy/fluxs/parse_html.rb
184
+ - lib/mushy/fluxs/pdf.rb
185
+ - lib/mushy/fluxs/print.rb
186
+ - lib/mushy/fluxs/pwd.rb
152
187
  - lib/mushy/fluxs/read_csv.rb
153
188
  - lib/mushy/fluxs/read_file.rb
154
189
  - lib/mushy/fluxs/screenshot.rb
190
+ - lib/mushy/fluxs/smtp.rb
155
191
  - lib/mushy/fluxs/write_file.rb
156
192
  - lib/mushy/masher.rb
157
193
  - lib/mushy/run.rb