nub 0.0.21

Sign up to get free protection for your applications and to get access to all the features.
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: []