nub 0.0.21

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 ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 102f1cf06e8b45889dd60b7372e5111f492a97fdf8ed8caafd30b3dac5690dd3
4
+ data.tar.gz: e921565b8a4ab7ef8644a1e0993d7187105840f38d73d21c6145cb420d7d8952
5
+ SHA512:
6
+ metadata.gz: 27f89bc3db8382e91415a3009d2cc76136734cf4f25685a5f40797b0cfdebabfc3fd5ff808eb4f84366c949bea3a5eebf38e8d333fcda2d58242f6716eb868f2
7
+ data.tar.gz: 5110db336085570bb0ec25497f4f61edc0f5d063de501e6edbbd01401846eb9c52a667d14b124f8363a7f853d94e0f8f71843b7be4e8653e832f5520ac127357
data/lib/nub.rb ADDED
@@ -0,0 +1,33 @@
1
+ #!/usr/bin/env ruby
2
+ #MIT License
3
+ #Copyright (c) 2018 phR0ze
4
+ #
5
+ #Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ #of this software and associated documentation files (the "Software"), to deal
7
+ #in the Software without restriction, including without limitation the rights
8
+ #to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ #copies of the Software, and to permit persons to whom the Software is
10
+ #furnished to do so, subject to the following conditions:
11
+ #
12
+ #The above copyright notice and this permission notice shall be included in all
13
+ #copies or substantial portions of the Software.
14
+ #
15
+ #THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ #IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ #FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ #AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ #LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ #OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ #SOFTWARE.
22
+
23
+ module Nub
24
+ require 'nub/cmds'
25
+ require 'nub/config'
26
+ require 'nub/log'
27
+ require 'nub/net'
28
+ require 'nub/string'
29
+ require 'nub/thread_comm'
30
+ require 'nub/user'
31
+ end
32
+
33
+ # vim: ft=ruby:ts=2:sw=2:sts=2
data/lib/nub/cmds.rb ADDED
@@ -0,0 +1,153 @@
1
+ #MIT License
2
+ #Copyright (c) 2018 phR0ze
3
+ #
4
+ #Permission is hereby granted, free of charge, to any person obtaining a copy
5
+ #of this software and associated documentation files (the "Software"), to deal
6
+ #in the Software without restriction, including without limitation the rights
7
+ #to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8
+ #copies of the Software, and to permit persons to whom the Software is
9
+ #furnished to do so, subject to the following conditions:
10
+ #
11
+ #The above copyright notice and this permission notice shall be included in all
12
+ #copies or substantial portions of the Software.
13
+ #
14
+ #THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15
+ #IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16
+ #FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17
+ #AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18
+ #LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19
+ #OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
20
+ #SOFTWARE.
21
+
22
+ require 'optparse' # cmd line options: OptionParser
23
+
24
+ begin
25
+ require 'colorize'
26
+ rescue Exception => e
27
+ mod = e.message.split(' ').last.sub('/', '-')
28
+ mod = e.message[/.*Could not find '(.*?)'.*/, 1] if e.message.include?("Could not find")
29
+ !puts("Error: install missing package with 'sudo pacman -S ruby-#{mod}'") and exit
30
+ end
31
+
32
+ # Command option class provides a way to encapsulate a command with
33
+ # any additional properties.
34
+ class CmdOpt
35
+ attr_reader(:key)
36
+ attr_reader(:conf)
37
+ attr_reader(:type)
38
+ attr_reader(:desc)
39
+ attr_reader(:required)
40
+ def initialize(conf, desc, type:nil, required:false)
41
+ @conf = conf.gsub(' ', '=')
42
+ @key = conf.gsub('-', '').split('=').first.to_sym
43
+ @type = type
44
+ @desc = desc
45
+ @required = required
46
+ end
47
+ end
48
+
49
+ # Simple command wrapper around options parsing
50
+ # When multiple commands are given they share the options passed along with them
51
+ class Cmds
52
+
53
+ # Option and command names have all hyphens removed
54
+ attr_accessor(:cmds)
55
+ attr_accessor(:opts)
56
+
57
+ # Initialize the commands for your application
58
+ # Params:
59
+ # +app+:: application name e.g. reduce
60
+ # +version+:: version of the application e.g. 1.0.0
61
+ # +examples+:: optional examples to list after the title before usage
62
+ def initialize(app, version, examples)
63
+ @opts = {}
64
+ @cmds = {}
65
+ @cmds_config = {}
66
+
67
+ @app = app
68
+ @version = version
69
+ @examples = examples || ''
70
+ end
71
+
72
+ # Hash like accessor for checking if a command is set
73
+ def [](key)
74
+ return @cmds[key] if @cmds[key]
75
+ return @opts[key] if @opts[key]
76
+ end
77
+
78
+ # Hash like accessor for editing options
79
+ def []=(key, value)
80
+ @opts[key] = value
81
+ end
82
+
83
+ # Add a command to the command list
84
+ # Params:
85
+ # +cmd+:: name of the command
86
+ # +desc+:: description of the command
87
+ # +opts+:: list of command options
88
+ def add(cmd, desc, opts)
89
+ @cmds_config[cmd] = {desc: desc, inopts: opts, outopts: OptionParser.new{|parser|
90
+ required = opts.map{|x| x.conf if x.required}.compact * ' '
91
+ required += ' ' if not required.empty?
92
+ parser.banner = "#{banner}\nUsage: ./#{@app} #{cmd} #{required}[options]"
93
+ opts.each{|opt| parser.on(opt.conf, opt.type, opt.desc){|x| @opts[opt.key] = x }}
94
+ }}
95
+ end
96
+
97
+ # Returns banner string
98
+ def banner
99
+ banner = "#{@app}_v#{@version}\n#{'-' * 80}".colorize(:light_yellow)
100
+ return banner
101
+ end
102
+
103
+ # Construct the command line parser and parse
104
+ def parse!
105
+
106
+ # Construct help for the application
107
+ help = "COMMANDS:\n"
108
+ @cmds_config.each{|k,v| help += " #{k.ljust(33, ' ')}#{v[:desc]}\n" }
109
+ help += "\nsee './#{@app} COMMAND --help' for specific command info"
110
+
111
+ # Construct top level option parser
112
+ @optparser = OptionParser.new do |parser|
113
+ parser.banner = "#{banner}\n#{@examples}Usage: ./#{@app} commands [options]"
114
+ parser.on('-h', '--help', 'Print command/options help') {|x| !puts(parser) and exit }
115
+ parser.separator(help)
116
+ end
117
+
118
+ # Invoke the option parser with help if any un-recognized commands are given
119
+ cmds = ARGV.select{|x| not x.start_with?('-')}
120
+ ARGV.clear and ARGV << '-h' if ARGV.empty? or cmds.any?{|x| not @cmds_config[x]}
121
+ cmds.each{|x| puts("Error: Invalid command '#{x}'".colorize(:red)) if not @cmds_config[x]}
122
+ @optparser.order!
123
+
124
+ # Now remove them from ARGV leaving only options
125
+ ARGV.reject!{|x| not x.start_with?('-')}
126
+
127
+ # Parse each command which will consume options from ARGV
128
+ cmds.each do |cmd|
129
+ begin
130
+ @cmds[cmd.gsub('-', '_').to_sym] = true
131
+ @cmds_config[cmd][:outopts].order!
132
+
133
+ # Ensure that all required options were given
134
+ @cmds_config[cmd][:inopts].each{|x|
135
+ if x.required and not @opts[x.key]
136
+ puts("Error: Missing required option '#{x.key}'".colorize(:red))
137
+ ARGV.clear and ARGV << "-h"
138
+ @cmds_config[cmd][:outopts].order!
139
+ end
140
+ }
141
+ rescue OptionParser::InvalidOption => e
142
+ # Options parser will raise an invalid exception if it doesn't recognize something
143
+ # However we want to ignore that as it may be another command's option
144
+ ARGV << e.to_s[/(-.*)/, 1]
145
+ end
146
+ end
147
+
148
+ # Ensure all options were consumed
149
+ !puts("Error: invalid options #{ARGV}".colorize(:red)) and exit if ARGV.any?
150
+ end
151
+ end
152
+
153
+ # vim: ft=ruby:ts=2:sw=2:sts=2
data/lib/nub/config.rb ADDED
@@ -0,0 +1,83 @@
1
+ #MIT License
2
+ #Copyright (c) 2018 phR0ze
3
+ #
4
+ #Permission is hereby granted, free of charge, to any person obtaining a copy
5
+ #of this software and associated documentation files (the "Software"), to deal
6
+ #in the Software without restriction, including without limitation the rights
7
+ #to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8
+ #copies of the Software, and to permit persons to whom the Software is
9
+ #furnished to do so, subject to the following conditions:
10
+ #
11
+ #The above copyright notice and this permission notice shall be included in all
12
+ #copies or substantial portions of the Software.
13
+ #
14
+ #THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15
+ #IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16
+ #FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17
+ #AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18
+ #LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19
+ #OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
20
+ #SOFTWARE.
21
+
22
+ require 'yaml'
23
+
24
+ begin
25
+ require 'colorize'
26
+ rescue Exception => e
27
+ mod = e.message.split(' ').last.sub('/', '-')
28
+ mod = e.message[/.*Could not find '(.*?)'.*/, 1] if e.message.include?("Could not find")
29
+ !puts("Error: install missing package with 'sudo pacman -S ruby-#{mod}'") and exit
30
+ end
31
+
32
+ require_relative 'user'
33
+ require_relative 'log'
34
+
35
+ # Simple YAML configuration for an application
36
+ # uses singleton pattern for single source of truth
37
+ module Config
38
+
39
+ # Private properties
40
+ @@_yml = nil
41
+
42
+ # Public properties
43
+ class << self
44
+ attr_accessor :path
45
+ end
46
+
47
+ # Singleton new alternate
48
+ # @param config_name [String] name of the config file
49
+ def self.init(config_name)
50
+ @path = "/home/#{User.name}/.config/#{config_name}"
51
+
52
+ # Open the config file or create in memory yml
53
+ begin
54
+ @@_yml = File.exists?(@path) ? YAML.load_file(@path) : {}
55
+ rescue Exception => e
56
+ Log.puts("Error: #{e}".colorize(:red)) and exit
57
+ end
58
+
59
+ return nil
60
+ end
61
+
62
+ # Simple bool whether the config exists or not on disk
63
+ def exists?
64
+ return File.exists?(@path)
65
+ end
66
+
67
+ # Hash like getter
68
+ def self.[](key)
69
+ return @@_yml[key]
70
+ end
71
+
72
+ # Hash like setter
73
+ def self.[]=(key, val)
74
+ return @@_yml[key] = val
75
+ end
76
+
77
+ # Save the config file
78
+ def self.save
79
+ File.open(@path, 'w'){|f| f << @@_yml.to_yaml } if @@_yml
80
+ end
81
+ end
82
+
83
+ # vim: ft=ruby:ts=2:sw=2:sts=2
data/lib/nub/log.rb ADDED
@@ -0,0 +1,254 @@
1
+ #MIT License
2
+ #Copyright (c) 2018 phR0ze
3
+ #
4
+ #Permission is hereby granted, free of charge, to any person obtaining a copy
5
+ #of this software and associated documentation files (the "Software"), to deal
6
+ #in the Software without restriction, including without limitation the rights
7
+ #to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8
+ #copies of the Software, and to permit persons to whom the Software is
9
+ #furnished to do so, subject to the following conditions:
10
+ #
11
+ #The above copyright notice and this permission notice shall be included in all
12
+ #copies or substantial portions of the Software.
13
+ #
14
+ #THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15
+ #IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16
+ #FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17
+ #AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18
+ #LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19
+ #OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
20
+ #SOFTWARE.
21
+
22
+ require 'time'
23
+ require 'monitor'
24
+ require 'ostruct'
25
+
26
+ begin
27
+ require 'colorize'
28
+ rescue Exception => e
29
+ mod = e.message.split(' ').last.sub('/', '-')
30
+ mod = e.message[/.*Could not find '(.*?)'.*/, 1] if e.message.include?("Could not find")
31
+ !puts("Error: install missing package with 'sudo pacman -S ruby-#{mod}'") and exit
32
+ end
33
+
34
+ ColorPair = Struct.new(:str, :color)
35
+ ColorMap = {
36
+ "30" => "black",
37
+ "31" => "red",
38
+ "32" => "green",
39
+ "33" => "yellow",
40
+ "34" => "blue",
41
+ "35" => "magenta",
42
+ "36" => "cyan",
43
+ "37" => "white",
44
+ "39" => "gray88" # default
45
+ }
46
+
47
+ LogLevel = OpenStruct.new({
48
+ error: 0,
49
+ warn: 1,
50
+ info: 2,
51
+ debug: 3
52
+ })
53
+
54
+ # Singleton logger for use with both console and gtk+ apps
55
+ # logs to both a file and the console/queue for shell/UI apps
56
+ # uses Mutex.synchronize where required to provide thread safty
57
+ module Log
58
+ extend self
59
+
60
+ # Private properties
61
+ @@_level = 3
62
+ @@_queue = nil
63
+ @@_stdout = true
64
+ @@_monitor = Monitor.new
65
+
66
+ # Public properties
67
+ class << self
68
+ attr_reader(:id, :path)
69
+ end
70
+
71
+ # Singleton new alternate initialize
72
+ # Can be called multiple times to reset
73
+ # @param path [String] path to log file
74
+ # @param queue [Bool] use a queue as well
75
+ # @param stdout [Bool] turn on or off stdout
76
+ # @param level [LogLevel] level at which to log
77
+ def init(path:nil, level:LogLevel.debug, queue:false, stdout:true)
78
+ @id ||= 'singleton'.object_id
79
+
80
+ @path = path ? File.expand_path(path) : nil
81
+ @@_level = level
82
+ @@_queue = queue ? Queue.new : nil
83
+ @@_stdout = stdout
84
+
85
+ # Open log file creating as needed
86
+ if @path
87
+ FileUtils.mkdir_p(File.dirname(@path)) if !File.exist?(File.dirname(@path))
88
+ @file = File.open(@path, 'a')
89
+ @file.sync = true
90
+ end
91
+
92
+ return nil
93
+ end
94
+
95
+ # Format the given string for use in log
96
+ def format(str)
97
+ @@_monitor.synchronize{
98
+
99
+ # Locate caller
100
+ stack = caller_locations(3,10)
101
+ i = -1
102
+ while i += 1 do
103
+ mod = File.basename(stack[i].path, '.rb')
104
+ break if !['log', 'monitor'].include?(mod)
105
+ end
106
+
107
+ # Save lineno from non log call but use method name rather than rescue or block
108
+ lineno = stack[i].lineno
109
+ nested = ['rescue in', 'block in', 'each']
110
+ while nested.any?{|x| stack[i].label.include?(x)} do
111
+ i += 1
112
+ end
113
+ loc = ":#{File.basename(stack[i].path, '.rb')}:#{stack[i].label}:#{lineno}"
114
+
115
+ return "#{Time.now.utc.iso8601(3)}#{loc}:: #{str}"
116
+ }
117
+ end
118
+
119
+ def print(*args)
120
+ @@_monitor.synchronize{
121
+ str = !args.first.is_a?(Hash) ? args.first.to_s : ''
122
+
123
+ # Determine if stamp should be used
124
+ stamp = true
125
+ opts = args.find{|x| x.is_a?(Hash)}
126
+ if opts and opts.key?(:stamp)
127
+ stamp = opts[:stamp]
128
+ end
129
+
130
+ # Format message
131
+ str = format(str) if stamp
132
+
133
+ if !str.empty?
134
+ @file << strip_colorize(str) if @path
135
+ @@_queue << str if @@_queue
136
+ $stdout.print(str) if @@_stdout
137
+ end
138
+
139
+ return true
140
+ }
141
+ end
142
+
143
+ def puts(*args)
144
+ @@_monitor.synchronize{
145
+ str = !args.first.is_a?(Hash) ? args.first.to_s : ''
146
+
147
+ # Determine if stamp should be used
148
+ stamp = true
149
+ opts = args.find{|x| x.is_a?(Hash)}
150
+ if opts and opts.key?(:stamp)
151
+ stamp = opts[:stamp]
152
+ end
153
+
154
+ # Format message
155
+ str = format(str) if stamp
156
+
157
+ # Handle output
158
+ @file.puts(strip_colorize(str)) if @path
159
+ @@_queue << "#{str}\n" if @@_queue
160
+ $stdout.puts(str) if @@_stdout
161
+
162
+ return true
163
+ }
164
+ end
165
+
166
+ def error(*args)
167
+ return puts(*args) if LogLevel.error <= @@_level
168
+ return true
169
+ end
170
+
171
+ def warn(*args)
172
+ return puts(*args) if LogLevel.warn <= @@_level
173
+ return true
174
+ end
175
+
176
+ def info(*args)
177
+ return puts(*args) if LogLevel.info <= @@_level
178
+ return true
179
+ end
180
+
181
+ def debug(*args)
182
+ return puts(*args) if LogLevel.debug <= @@_level
183
+ return true
184
+ end
185
+
186
+ # Log the given message in red and exit
187
+ # @param msg [String] message to log
188
+ def die(msg)
189
+ puts(msg.colorize(:red)) and exit
190
+ end
191
+
192
+ # Remove an item from the queue, block until one exists
193
+ def pop()
194
+ return @@_queue ? @@_queue.pop : nil
195
+ end
196
+
197
+ # Check if the log queue is empty
198
+ def empty?
199
+ return @@_queue ? @@_queue.empty? : true
200
+ end
201
+
202
+ # Strip the ansi color codes from the given string
203
+ # @param str [String] string with ansi color codes
204
+ # @returns [String] string without any ansi codes
205
+ def strip_colorize(str)
206
+ @@_monitor.synchronize{
207
+ return str.gsub(/\e\[0;[39]\d;49m/, '').gsub(/\e\[0m/, '')
208
+ }
209
+ end
210
+
211
+ # Tokenize the given colorized string
212
+ # @param str [String] string with ansi color codes
213
+ # @returns [Array] array of Token
214
+ def tokenize_colorize(str)
215
+ @@_monitor.synchronize{
216
+ tokens = []
217
+ matches = str.to_enum(:scan, /\e\[0;[39]\d;49m(.*?[\s]*)\e\[0m/).map{Regexp.last_match}
218
+
219
+ i, istart, iend = 0, 0, 0
220
+ match = matches[i]
221
+ while istart < str.size
222
+ color = "39"
223
+ iend = str.size
224
+ token = str[istart..iend]
225
+
226
+ # Current token is not a match
227
+ if match && match.begin(0) != istart
228
+ iend = match.begin(0)-1
229
+ token = str[istart..iend]
230
+ istart = iend + 1
231
+
232
+ # Current token is a match
233
+ elsif match && match.begin(0) == istart
234
+ iend = match.end(0)
235
+ token = match.captures.first
236
+ color = match.to_s[/\e\[0;(\d+);49m.*/, 1]
237
+ i += 1; match = matches[i]
238
+ istart = iend
239
+
240
+ # Ending
241
+ else
242
+ istart = iend
243
+ end
244
+
245
+ # Create token and advance
246
+ tokens << ColorPair.new(token, color)
247
+ end
248
+
249
+ return tokens
250
+ }
251
+ end
252
+ end
253
+
254
+ # vim: ft=ruby:ts=2:sw=2:sts=2
data/lib/nub/net.rb ADDED
@@ -0,0 +1,76 @@
1
+ #!/usr/bin/env ruby
2
+ #MIT License
3
+ #Copyright (c) 2018 phR0ze
4
+ #
5
+ #Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ #of this software and associated documentation files (the "Software"), to deal
7
+ #in the Software without restriction, including without limitation the rights
8
+ #to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ #copies of the Software, and to permit persons to whom the Software is
10
+ #furnished to do so, subject to the following conditions:
11
+ #
12
+ #The above copyright notice and this permission notice shall be included in all
13
+ #copies or substantial portions of the Software.
14
+ #
15
+ #THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ #IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ #FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ #AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ #LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ #OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ #SOFTWARE.
22
+ require 'ostruct'
23
+
24
+ module Net
25
+ @@_proxy = nil
26
+ @@_agents = OpenStruct.new({
27
+ windows_ie_6: 'Windows IE 6',
28
+ windows_ie_7: 'Windows IE 7',
29
+ windows_mozilla: 'Windows Mozilla',
30
+ mac_safari: 'Mac Safari',
31
+ mac_firefox: 'Mac FireFox',
32
+ mac_mozilla: 'Mac Mozilla',
33
+ linux_mozilla: 'Linux Mozilla',
34
+ linux_firefox: 'Linux Firefox',
35
+ linux_konqueror: 'Linux Konqueror',
36
+ iphone: 'iPhone'
37
+ })
38
+
39
+ # Accessors
40
+ def self.agents; @@_agents; end
41
+ def self.proxy_uri; http_proxy ? http_proxy.split(':')[1][2..-1] : nil; end
42
+ def self.proxy_port; http_proxy ? http_proxy.split(':').last : nil; end
43
+ def self.ftp_proxy; get_proxy if @@_proxy.nil?; @@_proxy['ftp_proxy']; end
44
+ def self.http_proxy; get_proxy if @@_proxy.nil?; @@_proxy['http_proxy']; end
45
+ def self.https_proxy; get_proxy if @@_proxy.nil?; @@_proxy['https_proxy']; end
46
+ def self.no_proxy; get_proxy if @@_proxy.nil?; @@_proxy['no_proxy']; end
47
+
48
+ # Get the system proxy variables
49
+ def self.get_proxy
50
+ @@_proxy = {
51
+ 'ftp_proxy' => ENV['ftp_proxy'],
52
+ 'http_proxy' => ENV['http_proxy'],
53
+ 'https_proxy' => ENV['https_proxy'],
54
+ 'no_proxy' => ENV['no_proxy']
55
+ }
56
+ end
57
+
58
+ # Get a shell export string for proxies
59
+ def self.proxy_export
60
+ get_proxy if @@_proxy.nil?
61
+ return proxy_exist? ? (@@_proxy.map{|k,v| "export #{k}=#{v}"} * ';') + ";" : nil
62
+ end
63
+
64
+ # Check if a proxy is set
65
+ def self.proxy_exist?
66
+ get_proxy if @@_proxy.nil?
67
+ return !@@_proxy['http_proxy'].nil?
68
+ end
69
+
70
+ # Check if the system is configured for the kernel to forward ip traffic
71
+ def self.ip_forward?
72
+ return `cat /proc/sys/net/ipv4/ip_forward`.include?('1')
73
+ end
74
+ end
75
+
76
+ # vim: ft=ruby:ts=2:sw=2:sts=2
data/lib/nub/string.rb ADDED
@@ -0,0 +1,35 @@
1
+ #MIT License
2
+ #Copyright (c) 2018 phR0ze
3
+ #
4
+ #Permission is hereby granted, free of charge, to any person obtaining a copy
5
+ #of this software and associated documentation files (the "Software"), to deal
6
+ #in the Software without restriction, including without limitation the rights
7
+ #to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8
+ #copies of the Software, and to permit persons to whom the Software is
9
+ #furnished to do so, subject to the following conditions:
10
+ #
11
+ #The above copyright notice and this permission notice shall be included in all
12
+ #copies or substantial portions of the Software.
13
+ #
14
+ #THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15
+ #IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16
+ #FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17
+ #AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18
+ #LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19
+ #OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
20
+ #SOFTWARE.
21
+
22
+ # Monkey patch string with some useful methods
23
+ class String
24
+ def to_ascii
25
+ options = {
26
+ :invalid => :replace,
27
+ :undef => :replace,
28
+ :replace => '',
29
+ :universal_newline => true
30
+ }
31
+ return self.encode(Encoding.find('ASCII'), options)
32
+ end
33
+ end
34
+
35
+ # vim: ft=ruby:ts=2:sw=2:sts=2
@@ -0,0 +1,65 @@
1
+ #MIT License
2
+ #Copyright (c) 2018 phR0ze
3
+ #
4
+ #Permission is hereby granted, free of charge, to any person obtaining a copy
5
+ #of this software and associated documentation files (the "Software"), to deal
6
+ #in the Software without restriction, including without limitation the rights
7
+ #to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8
+ #copies of the Software, and to permit persons to whom the Software is
9
+ #furnished to do so, subject to the following conditions:
10
+ #
11
+ #The above copyright notice and this permission notice shall be included in all
12
+ #copies or substantial portions of the Software.
13
+ #
14
+ #THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15
+ #IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16
+ #FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17
+ #AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18
+ #LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19
+ #OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
20
+ #SOFTWARE.
21
+
22
+ require 'ostruct'
23
+
24
+ # Provides a simple messaging mechanism between threads
25
+ ThreadMsg = Struct.new(:cmd, :value)
26
+
27
+ # Thread with communication queues for simple messaging
28
+ class ThreadComm < Thread
29
+ def initialize
30
+ @comm_in = Queue.new
31
+ @comm_out = Queue.new
32
+
33
+ # Proc.new will return the block given to this method
34
+ # pass it along to thread .new with arguments
35
+ super(@comm_in, @comm_out, &Proc.new)
36
+ end
37
+
38
+ # Check if the message queue is empty
39
+ def empty?
40
+ return @comm_out.empty?
41
+ end
42
+
43
+ # Pop a message off the thread's outbound queue or block
44
+ def pop
45
+ msg = @comm_out.pop
46
+ return msg if msg.is_a?(ThreadMsg)
47
+ return ThreadMsg.new(msg)
48
+ end
49
+
50
+ # Push the given message onto the threads inbound queue
51
+ # @param msg [ThreadMsg] message to the thread
52
+ # @param cmd [String] message command to the thread
53
+ # @param value [String] message value to the thread
54
+ def push(*args)
55
+ if args.first.is_a?(ThreadMsg)
56
+ @comm_in << args.first
57
+ elsif args.size == 1
58
+ @comm_in << ThreadMsg.new(args.first)
59
+ else
60
+ @comm_in << ThreadMsg.new(args.first, args.last)
61
+ end
62
+ end
63
+ end
64
+
65
+ # vim: ft=ruby:ts=2:sw=2:sts=2
data/lib/nub/user.rb ADDED
@@ -0,0 +1,36 @@
1
+ #!/usr/bin/env ruby
2
+ #MIT License
3
+ #Copyright (c) 2018 phR0ze
4
+ #
5
+ #Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ #of this software and associated documentation files (the "Software"), to deal
7
+ #in the Software without restriction, including without limitation the rights
8
+ #to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ #copies of the Software, and to permit persons to whom the Software is
10
+ #furnished to do so, subject to the following conditions:
11
+ #
12
+ #The above copyright notice and this permission notice shall be included in all
13
+ #copies or substantial portions of the Software.
14
+ #
15
+ #THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ #IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ #FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ #AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ #LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ #OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ #SOFTWARE.
22
+
23
+ module User
24
+
25
+ # Check if the current user has root privileges
26
+ def self.root?
27
+ return Process.uid.zero?
28
+ end
29
+
30
+ # Get the current user taking into account sudo priviledges
31
+ def self.name
32
+ return Process.uid.zero? ? Etc.getpwuid(ENV['SUDO_UID'].to_i).name : ENV['USER']
33
+ end
34
+ end
35
+
36
+ # vim: ft=ruby:ts=2:sw=2:sts=2
metadata ADDED
@@ -0,0 +1,51 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: nub
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.21
5
+ platform: ruby
6
+ authors:
7
+ - Patrick Crummett
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2018-03-22 00:00:00.000000000 Z
12
+ dependencies: []
13
+ description: Collection of useful utilities
14
+ email:
15
+ executables: []
16
+ extensions: []
17
+ extra_rdoc_files: []
18
+ files:
19
+ - lib/nub.rb
20
+ - lib/nub/cmds.rb
21
+ - lib/nub/config.rb
22
+ - lib/nub/log.rb
23
+ - lib/nub/net.rb
24
+ - lib/nub/string.rb
25
+ - lib/nub/thread_comm.rb
26
+ - lib/nub/user.rb
27
+ homepage: https://github.com/phR0ze/ruby-nub
28
+ licenses:
29
+ - MIT
30
+ metadata: {}
31
+ post_install_message:
32
+ rdoc_options: []
33
+ require_paths:
34
+ - lib
35
+ required_ruby_version: !ruby/object:Gem::Requirement
36
+ requirements:
37
+ - - ">="
38
+ - !ruby/object:Gem::Version
39
+ version: '0'
40
+ required_rubygems_version: !ruby/object:Gem::Requirement
41
+ requirements:
42
+ - - ">="
43
+ - !ruby/object:Gem::Version
44
+ version: '0'
45
+ requirements: []
46
+ rubyforge_project:
47
+ rubygems_version: 2.7.3
48
+ signing_key:
49
+ specification_version: 4
50
+ summary: Collection of useful utilities
51
+ test_files: []