epitools 0.5.124 → 0.5.130

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: 6ccc18312dec46b4af2100239be52ac5db3ce4aaf7c3cbdb8a325ec656fff6f9
4
- data.tar.gz: 2e68f10fc0006ef3dec61493d8950103a24e05f1ed24afc967bcfdb38e758282
3
+ metadata.gz: d5b52f237d17762dca9dfa53fa0cbdae372f867f84fb455ca97656a9863d6763
4
+ data.tar.gz: 25f2741a4a12dc257ef1d540dcbfea1e6fa7945267de324e1ddba4e860d44334
5
5
  SHA512:
6
- metadata.gz: d65bbb00c1359e587f18399dbd952386f6beceae05c04201c8d0e97aec735c70b573cc337f56657ac372334202081b4c2c568a7753bc79f1e52f347fea1786e0
7
- data.tar.gz: 07c4623c4bd5217ebdce11fcb373ad27406e0d5d6eb8c0bd8f6c0e087c39c281a1146b757b9606da37026d01c791d8462bf62966ace409535f7f21e7d1d4b2a5
6
+ metadata.gz: 264e9ab8322afd8b6e08b3445dde07c4bf214a9da6e0b087e2c1117a5f0366edd5db361afd64a91faa24988618cf6fccf940ab7bfa7e76b63d8d53a905ef32ae
7
+ data.tar.gz: 0bb9e187d248d149e60c05fbf7a5757a79d560e1452a6ccf808294fc0cb0816d6e9de53d997e2fdeba49056c09a0d55bb8de6b06332174bcdfafe2c6fc004fbb
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.5.124
1
+ 0.5.130
@@ -1,7 +1,6 @@
1
1
  ## Standard library
2
2
 
3
3
  autoload :Set, 'set'
4
- autoload :URI, 'uri'
5
4
  autoload :Zlib, 'zlib'
6
5
  autoload :FileUtils, 'fileutils'
7
6
  autoload :Tempfile, 'tempfile'
@@ -23,6 +22,10 @@ autoload :CSV, 'csv'
23
22
  autoload :SDBM, 'sdbm'
24
23
  autoload :StringScanner, 'strscan'
25
24
 
25
+ autoreq :URI do
26
+ require 'epitools/core_ext/uri'
27
+ end
28
+
26
29
  module Digest
27
30
  autoload :SHA1, 'digest/sha1'
28
31
  autoload :SHA2, 'digest/sha2'
@@ -62,26 +65,32 @@ autoload :IPAddr, 'ipaddr'
62
65
 
63
66
  ## Nonstandard library (epitools)
64
67
 
65
- autoload :Path, 'epitools/path'
66
- autoload :Ezdb, 'epitools/ezdb'
67
- autoload :Browser, 'epitools/browser'
68
- autoload :Rash, 'epitools/rash'
69
- autoload :Ratio, 'epitools/ratio'
70
- autoload :ProgressBar, 'epitools/progressbar'
71
- autoload :Trie, 'epitools/trie'
72
- autoload :MimeMagic, 'epitools/mimemagic'
73
- autoload :Term, 'epitools/term'
74
- autoload :Iter, 'epitools/iter'
75
- autoload :WM, 'epitools/wm'
76
- autoload :TypedStruct, 'epitools/typed_struct'
77
- autoload :Sys, 'epitools/sys'
68
+ autoload :Path, 'epitools/path'
69
+ autoload :Ezdb, 'epitools/ezdb'
70
+ autoload :Browser, 'epitools/browser'
71
+ autoload :Rash, 'epitools/rash'
72
+ autoload :Ratio, 'epitools/ratio'
73
+ autoload :ProgressBar, 'epitools/progressbar'
74
+ autoload :Trie, 'epitools/trie'
75
+ autoload :MimeMagic, 'epitools/mimemagic'
76
+ autoload :Term, 'epitools/term'
77
+ autoload :Iter, 'epitools/iter'
78
+ autoload :WM, 'epitools/wm'
79
+ autoload :TypedStruct, 'epitools/typed_struct'
80
+ autoload :Sys, 'epitools/sys'
81
+ autoload :JobRunner, 'epitools/job_runner'
78
82
  autoload :SemanticVersion, 'epitools/semantic_version'
79
83
 
80
84
  autoload :Matrix, 'epitools/core_ext/matrix'
81
85
  autoreq(:Vector) { Matrix }
82
86
 
83
- module Epi; autoload :Slop, 'epitools/slop'; end
84
- autoreq(:Slop) { Slop = Epi::Slop }
87
+ ## Bundled slop
88
+ module Epi
89
+ autoload :Slop, 'epitools/slop'
90
+ end
91
+ autoreq(:Slop) do
92
+ Slop = Epi::Slop
93
+ end
85
94
 
86
95
  ## Gems (common)
87
96
 
@@ -230,3 +230,20 @@ def notify_send(title, body=nil, icon: nil, time: 5)
230
230
  fork { system *cmd }
231
231
  end
232
232
 
233
+ def curl(url)
234
+ curl_open(url).read
235
+ end
236
+
237
+ def curl_open(url, headers={})
238
+ # headers["User-Agent"] ||= "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_5) AppleWebKit/605.1.15 (KHTML, like Gecko) CriOS/85 Version/11.1.1 Safari/605.1.15"
239
+ cmd = ["curl", "-LSs"]
240
+ headers.each { |k,v| cmd += ["-H", "#{k}: #{v}"] }
241
+ cmd << url
242
+ IO.popen(cmd)
243
+ rescue Errno::ENOENT
244
+ raise "Error: 'curl' isn't installed."
245
+ end
246
+
247
+ def curl_json(url)
248
+ JSON.parse(curl(url))
249
+ end
@@ -5,16 +5,23 @@ require 'epitools'
5
5
  require 'epitools/core_ext/object'
6
6
  require 'epitools/core_ext/class'
7
7
  require 'epitools/core_ext/module'
8
+
8
9
  require 'epitools/core_ext/string'
10
+
9
11
  require 'epitools/core_ext/array'
10
- require 'epitools/core_ext/file'
11
- require 'epitools/core_ext/io'
12
12
  require 'epitools/core_ext/enumerable'
13
13
  require 'epitools/core_ext/hash'
14
+
14
15
  require 'epitools/core_ext/numbers'
15
16
  require 'epitools/core_ext/truthiness'
16
17
  require 'epitools/core_ext/range'
17
18
  require 'epitools/core_ext/time'
19
+
20
+ require 'epitools/core_ext/argv'
21
+ require 'epitools/core_ext/file'
22
+ require 'epitools/core_ext/io'
23
+ require 'epitools/core_ext/uri'
24
+
18
25
  require 'epitools/core_ext/misc'
19
26
 
20
27
  ##############################################################################
@@ -0,0 +1,59 @@
1
+ class << ARGV
2
+
3
+ def parse!
4
+ unless @opts or @args
5
+ @opts, @args = partition { |arg| arg[/^--?\w{1,2}/].nil? }
6
+ @opts = @opts.map { |opt| key, val = opt.strip(/^-+/).split("=") }.to_ostruct
7
+ if @opts.help
8
+ @help_handler.call
9
+ exit
10
+ end
11
+ end
12
+
13
+ [@opts, @args]
14
+ end
15
+
16
+ def parse
17
+ parse!
18
+ [@opts, @args]
19
+ end
20
+
21
+ def help?
22
+ !!@opts["help"]
23
+ end
24
+
25
+ def opts
26
+ parse! unless @opts
27
+ @opts
28
+ end
29
+
30
+ def args
31
+ @args ? @args : opts && @args
32
+ end
33
+
34
+ def paths
35
+ map(&:to_Path)
36
+ end
37
+
38
+ def paths_R
39
+ recursive_proc = proc do |paths|
40
+ paths.map { |path| path.dir? ? the_expander.(path.ls_R) : path }
41
+ end
42
+
43
+ recursive_proc.(paths)
44
+ end
45
+ alias_method :recursive_paths, :paths_R
46
+
47
+ def on_help(&block)
48
+ @help_handler = block
49
+ end
50
+
51
+ def regexes(escaped: true, case_sensitive: false)
52
+ if case_sensitive
53
+ map { |arg| /#{escaped ? Regexp.escape(arg) : arg}/ } # NO 'i'
54
+ else
55
+ map { |arg| /#{escaped ? Regexp.escape(arg) : arg}/i }
56
+ end
57
+ end
58
+
59
+ end
@@ -324,6 +324,33 @@ class Array
324
324
  super.to_a
325
325
  end
326
326
 
327
- end
327
+ module ToCSV
328
+ #
329
+ # Convert this enumerable into a CSV string (nb: enumerable must contain either all Hashes or all Arrays)
330
+ #
331
+ def to_csv(delimiter=",")
332
+ types = count_by(&:class)
333
+
334
+ unless types.size == 1 and (types[Array] > 0 or types[Hash] > 0)
335
+ raise "Error: this array must contain nothing but arrays, or nothing but hashes (actually contains: #{types.inspect})"
336
+ end
337
+
338
+ options = {}
339
+ options[:col_sep] = delimiter
340
+ options[:headers] = flat_map(&:keys).uniq if types[Hash] > 0
328
341
 
342
+ CSV.generate(nil, **options) do |csv|
343
+ each { |obj| csv << obj }
344
+ end
345
+ end
329
346
 
347
+ #
348
+ # Like #to_csv, but with tab-separated CSV fields
349
+ #
350
+ def to_tsv
351
+ to_csv("\t")
352
+ end
353
+ end
354
+
355
+ prepend ToCSV # dirty hack to stop the CSV module from clobbering the to_csv method
356
+ end
@@ -1,31 +1,17 @@
1
1
  class Class
2
2
 
3
- #
4
- # Return a copy of the class with modules mixed into it.
5
- #
6
- def self.using(*args)
7
- if block_given?
8
- yield using(*args)
9
- else
10
- copy = self.dup
11
- args.each { |arg| copy.send(:include, arg) }
12
- copy
13
- end
14
- end
15
-
16
-
17
3
  #
18
4
  # Trace the specified method calls (`meths`, as symbols) to descendends of this class (or all methods if `:*` is supplied).
19
5
  # Output is printed to $stderr.
20
6
  #
21
7
  def trace_messages_to(*meths)
22
8
  return unless $DEBUG
23
-
9
+
24
10
  tracers = Module.new
25
11
  parent = self
26
12
 
27
13
  $stderr.puts "[*] Tracing messages sent to #{parent} (messages: #{meths.join(", ")})"
28
-
14
+
29
15
  meths.each do |meth|
30
16
  case meth
31
17
  when :*
@@ -35,9 +21,9 @@ class Class
35
21
  end
36
22
  else
37
23
  tracers.define_method(meth) do |*args, &block|
38
- args = args.map(&:inspect)
39
- args << "&block" if block
40
- $stderr.puts "[*] #{parent}##{meth}(#{args.join(", ")})"
24
+ arg_names = args.map(&:inspect)
25
+ arg_names << "&block" if block
26
+ $stderr.puts "[*] #{parent}##{meth}(#{arg_names.join(", ")})"
41
27
  if block
42
28
  super(*args, &block)
43
29
  else
@@ -1,4 +1,7 @@
1
+ require 'epitools/core_ext/array'
2
+
1
3
  module Enumerable
4
+ include Array::ToCSV
2
5
 
3
6
  #
4
7
  # 'true' if the Enumerable has no elements
@@ -128,79 +128,6 @@ end
128
128
 
129
129
 
130
130
 
131
- module URI
132
-
133
- #
134
- # Return a Hash of the variables in the query string
135
- #
136
- def params
137
- query ? query.to_params : {}
138
- end
139
-
140
- #
141
- # URIs are strings, dammit!
142
- #
143
- def to_str
144
- to_s
145
- end
146
-
147
- #
148
- # Default user agent for the 'get' method
149
- #
150
- # USER_AGENT = "Mozilla/5.0 (X11; Linux x86_64; rv:61.0) Gecko/20100101 Firefox/61.0"
151
-
152
- #
153
- # Get this URI using Net::HTTP
154
- #
155
- def get(headers={}, redirect_limit=10)
156
- raise "Sorry, URI can't get from #{scheme.inspect} URIs yet" unless scheme =~ /^https?$/
157
- raise 'Too many HTTP redirections' if redirect_limit == 0
158
-
159
- # headers['User-Agent'] ||= USER_AGENT
160
-
161
- # response = Net::HTTP.start(host, port) do |http|
162
- # # the_path = path.empty? ? "/" : path
163
- # req = Net::HTTP::Get.new(self, headers)
164
- # http.request(req)
165
- # end
166
-
167
- response = Net::HTTP.get_response(self)
168
-
169
- case response
170
- when Net::HTTPSuccess
171
- response
172
- when Net::HTTPRedirection
173
- # puts "redirect: #{response['location']}"
174
- URI(response['location']).get(headers, redirect_limit-1)
175
- else
176
- response.error!
177
- end
178
- end
179
-
180
- end
181
-
182
- #
183
- # Stupid workaround for URI blowing up when it receives a [ or ] character
184
- #
185
- module Better_URI_RFC3986_Parser # ::RFC3986_relative_ref
186
- ESCAPE_ME_PLZ = "[]{}!"
187
-
188
- def split(uri)
189
- subsitutions = ESCAPE_ME_PLZ.chars.map { |c| [c, CGI.escape(c)] }
190
- subsitutions << [" ", "%20"]
191
-
192
- subsitutions.each do |find, replace|
193
- uri = uri.gsub(find, replace)
194
- end
195
-
196
- super(uri)
197
- end
198
-
199
- end
200
-
201
- URI::RFC3986_Parser.prepend(Better_URI_RFC3986_Parser)
202
-
203
-
204
131
 
205
132
  #
206
133
  # Give ObjectSpace Enumerable powers (select, map, etc.)
@@ -1,5 +1,5 @@
1
1
 
2
- Number = Numeric # "obj.is_a? Number" just sounds better.
2
+ Number = Numeric # because "obj.is_a? Number" sounds better!
3
3
 
4
4
  class Numeric
5
5
 
@@ -84,7 +84,8 @@ class Numeric
84
84
  end
85
85
  end
86
86
 
87
- [:cos,
87
+ [
88
+ :cos,
88
89
  :sin,
89
90
  :tan,
90
91
  :acos,
@@ -186,7 +187,8 @@ class Numeric
186
187
  end
187
188
 
188
189
  BYTE_SIZE_TABLE = {
189
- # power # units
190
+ # power
191
+ # of 1024 # units
190
192
  0 => "",
191
193
  1 => "KB",
192
194
  2 => "MB",
@@ -213,8 +215,8 @@ class Numeric
213
215
  def to_hms
214
216
  seconds = self
215
217
 
216
- days, seconds = seconds.divmod(86400)
217
- hours, seconds = seconds.divmod(3600)
218
+ days, seconds = seconds.divmod(86400)
219
+ hours, seconds = seconds.divmod(3600)
218
220
  minutes, seconds = seconds.divmod(60)
219
221
  seconds, frac = seconds.divmod(1)
220
222
 
@@ -229,8 +231,8 @@ class Numeric
229
231
  def to_hms_in_words
230
232
  seconds = self
231
233
 
232
- days, seconds = seconds.divmod(86400)
233
- hours, seconds = seconds.divmod(3600)
234
+ days, seconds = seconds.divmod(86400)
235
+ hours, seconds = seconds.divmod(3600)
234
236
  minutes, seconds = seconds.divmod(60)
235
237
  seconds, frac = seconds.divmod(1)
236
238
 
@@ -243,6 +245,14 @@ class Numeric
243
245
  result
244
246
  end
245
247
 
248
+ def to_farenheit
249
+ (self * 9.0 / 5.0) + 32
250
+ end
251
+
252
+ def to_celcius
253
+ (self - 32) * 5.0 / 9.0
254
+ end
255
+
246
256
  end
247
257
 
248
258
 
@@ -442,7 +452,8 @@ end
442
452
  class Prime
443
453
 
444
454
  #
445
- # Return an array of prime numbers within the specified range
455
+ # Return an array of prime numbers within the specified range.
456
+ # (It still has to generate all the primes less than the lower bound, so, yeah... be warned.)
446
457
  #
447
458
  def [](range)
448
459
  ubound = range.end
@@ -0,0 +1,103 @@
1
+ require 'uri'
2
+
3
+ class URI::Generic
4
+
5
+ #
6
+ # Get the query string
7
+ #
8
+ def query
9
+ params.to_query
10
+ end
11
+
12
+ #
13
+ # Return a Hash of the variables in the query string
14
+ #
15
+ def params
16
+ @params ||= (@query ? @query.to_params : {})
17
+ end
18
+
19
+ #
20
+ # Update all the params at once
21
+ #
22
+ def params=(new_params)
23
+ # self.query = new_params.to_params
24
+ raise "params must be a Hash" unless new_params.is_a? Hash
25
+ @params = new_params
26
+ end
27
+
28
+ # #
29
+ # # Update one URI parameter
30
+ # #
31
+ # def set_param(key, value)
32
+ # current = params
33
+ # current[key] = value
34
+ # self.query = current.to_query
35
+ # end
36
+
37
+ #
38
+ # URIs *are* strings, dammit!
39
+ #
40
+ def to_str
41
+ to_s
42
+ end
43
+
44
+ end
45
+
46
+ module URI
47
+
48
+ #
49
+ # Default user agent for the 'get' method
50
+ #
51
+ # USER_AGENT = "Mozilla/5.0 (X11; Linux x86_64; rv:61.0) Gecko/20100101 Firefox/61.0"
52
+
53
+ #
54
+ # Get this URI using Net::HTTP
55
+ #
56
+ def get(headers={}, redirect_limit=10)
57
+ raise "Sorry, URI can't get from #{scheme.inspect} URIs yet" unless scheme =~ /^https?$/
58
+ raise 'Too many HTTP redirections' if redirect_limit == 0
59
+
60
+ # headers['User-Agent'] ||= USER_AGENT
61
+
62
+ # response = Net::HTTP.start(host, port) do |http|
63
+ # # the_path = path.empty? ? "/" : path
64
+ # req = Net::HTTP::Get.new(self, headers)
65
+ # http.request(req)
66
+ # end
67
+
68
+ response = Net::HTTP.get_response(self)
69
+
70
+ case response
71
+ when Net::HTTPSuccess
72
+ response
73
+ when Net::HTTPRedirection
74
+ # puts "redirect: #{response['location']}"
75
+ URI(response['location']).get(headers, redirect_limit-1)
76
+ else
77
+ response.error!
78
+ end
79
+ end
80
+
81
+ end
82
+
83
+ #
84
+ # Stupid workaround for URI blowing up when it receives a [ or ] character
85
+ #
86
+ module Better_URI_RFC3986_Parser # ::RFC3986_relative_ref
87
+ ESCAPE_ME_PLZ = "[]{}!"
88
+
89
+ def split(uri)
90
+ subsitutions = ESCAPE_ME_PLZ.chars.map { |c| [c, CGI.escape(c)] }
91
+ subsitutions << [" ", "%20"]
92
+
93
+ subsitutions.each do |find, replace|
94
+ uri = uri.gsub(find, replace)
95
+ end
96
+
97
+ super(uri)
98
+ end
99
+
100
+ end
101
+
102
+ URI::RFC3986_Parser.prepend(Better_URI_RFC3986_Parser)
103
+
@@ -0,0 +1,97 @@
1
+ #
2
+ # Runs many jobs in parallel, and returns their interleaved results.
3
+ # (NOTE: The JobRunner can be run multiple times; each time the blocks
4
+ # will be executed again.)
5
+ #
6
+ # Examples:
7
+ #
8
+ # JobRunner.new do |jr|
9
+ # jr.add { 3 }
10
+ # jr.add { sleep 0.1; 2 }
11
+ # jr.add { sleep 0.2; 1 }
12
+ #
13
+ # jr.each_result do |result|
14
+ # p result
15
+ # end
16
+ # end
17
+ #
18
+ # jr = JobRunner.new(
19
+ # proc { 1 },
20
+ # proc { 2 },
21
+ # proc { 3 }
22
+ # )
23
+ #
24
+ # 2.times do
25
+ # jr.each_result { |result| p result }
26
+ # end
27
+ #
28
+ class JobRunner
29
+ def initialize(*blocks)
30
+ @threads = []
31
+ @results = Thread::Queue.new
32
+ @jobs = []
33
+ @started = false
34
+
35
+ if blocks.any?
36
+ blocks.each { |block| add &block }
37
+ else
38
+ yield self if block_given?
39
+ end
40
+ end
41
+
42
+ def add(&block)
43
+ @jobs << block
44
+ end
45
+
46
+ def reap!
47
+ @threads.delete_if { |t| not t.alive? } if @threads.any?
48
+ end
49
+
50
+ def go!
51
+ raise "Error: already started" if @started
52
+ @started = true
53
+ @jobs.each do |job|
54
+ @threads << Thread.new do
55
+ @results << job.call
56
+ end
57
+ end
58
+ end
59
+
60
+ def each_result
61
+ go! unless @started
62
+
63
+ loop do
64
+ yield @results.pop
65
+ reap!
66
+ break if @threads.empty? and @results.empty?
67
+ end
68
+
69
+ @started = false
70
+ end
71
+ end
72
+
73
+
74
+ if __FILE__ == $0
75
+ JobRunner.new do |jr|
76
+ jr.add { 3 }
77
+ jr.add { sleep 0.1; 2 }
78
+ jr.add { sleep 0.2; 1 }
79
+
80
+ jr.each_result do |result|
81
+ p result
82
+ end
83
+ end
84
+
85
+ puts
86
+
87
+ jr = JobRunner.new(
88
+ proc { 1 },
89
+ proc { 2 },
90
+ proc { 3 }
91
+ )
92
+
93
+ 2.times do
94
+ jr.each_result { |r| p r }
95
+ puts
96
+ end
97
+ end
@@ -1,8 +1,10 @@
1
+ ####################################################################################
1
2
  #
2
3
  # If you require 'epitools/minimal' instead of 'epitools',
3
4
  # this is what you get: core_ext monkeypatches and all the
4
5
  # autoloads; the barest essentials for survival.
5
6
  #
7
+ ####################################################################################
6
8
 
7
9
  if RUBY_VERSION[/^1.8/]
8
10
  require 'enumerator'
@@ -14,6 +16,7 @@ RbConfig = Config unless defined? RbConfig
14
16
  Infinity = Float::INFINITY
15
17
  Inf = Float::INFINITY
16
18
 
19
+ ####################################################################################
17
20
  class Object
18
21
 
19
22
  unless defined?(__DIR__)
@@ -164,14 +167,13 @@ class Object
164
167
  #
165
168
  # eg: stuff.group_by(&:self)
166
169
  #
167
- define_method :self do
170
+ def self
168
171
  if block_given?
169
172
  yield self
170
173
  else
171
174
  self
172
175
  end
173
176
  end
174
- alias_method :fap, :self
175
177
 
176
178
  def ancestors
177
179
  self.class.ancestors
@@ -179,6 +181,7 @@ class Object
179
181
  end
180
182
 
181
183
 
184
+ ####################################################################################
182
185
  #
183
186
  # Patch 'Module#const_missing' to support 'autoreq' (which can autoload gems)
184
187
  #
@@ -213,6 +216,8 @@ class Module
213
216
  end
214
217
 
215
218
 
219
+
220
+ ####################################################################################
216
221
  module Kernel
217
222
 
218
223
  #
@@ -254,10 +259,8 @@ module Kernel
254
259
  end
255
260
 
256
261
  end
257
- ####################################################################################
258
-
259
-
260
262
 
263
+ ####################################################################################
261
264
  class String
262
265
 
263
266
  #
@@ -270,6 +273,7 @@ class String
270
273
 
271
274
  end
272
275
 
276
+ ####################################################################################
273
277
  #
274
278
  # Path("/some/path") is an alias for Path["/some/path"]
275
279
  #
@@ -277,43 +281,7 @@ def Path(arg)
277
281
  Path[arg]
278
282
  end
279
283
 
280
- ####################################################################
281
-
282
- # class << ARGV
283
-
284
- # def opts
285
- # @opts, @args ||= partition { |arg| arg[/^--?\w{1,2}/].nil? }
286
- # end
287
-
288
- # def args
289
- # @args ? @args : opts && @args
290
- # end
291
-
292
- # def paths
293
- # map(&:to_Path)
294
- # end
295
-
296
- # def paths_R
297
- # recursive_proc = proc do |paths|
298
- # paths.map { |path| path.dir? ? the_expander.(path.ls_R) : path }
299
- # end
300
-
301
- # recursive_proc.(paths)
302
- # end
303
- # alias_method :recursive_paths, :paths_R
304
-
305
- # def regexes(escaped: true, case_sensitive: false)
306
- # if case_sensitive
307
- # map { |arg| /#{escaped ? Regexp.escape(arg) : arg}/ } # NO 'i'
308
- # else
309
- # map { |arg| /#{escaped ? Regexp.escape(arg) : arg}/i }
310
- # end
311
- # end
312
-
313
- # end
314
284
 
315
285
  ####################################################################
316
-
317
286
  require 'epitools/autoloads'
318
-
319
287
  ####################################################################
@@ -4,6 +4,7 @@ require 'epitools/minimal'
4
4
  # Cross-platform operating system functions.
5
5
  # Includes: process listing, platform detection, etc.
6
6
  #
7
+ require 'epitools/sys/os'
7
8
  require 'epitools/sys/ps'
8
9
  require 'epitools/sys/mounts'
9
10
  require 'epitools/sys/misc'
@@ -61,7 +61,7 @@ module WM
61
61
 
62
62
  def self.all
63
63
  # FIXME: Windows owned by linux-namespaced processes (firejail) report their namspaced pid to X11. `window.process` ends up pointing at either nil, or the wrong process.
64
- `wmctrl -lpG`.lines.map(&:strip).map { |line| Window.from_line(line) }
64
+ `wmctrl -lpG`.lines.map(&:strip).map { |line| Window.from_line(line) unless line.blank? }.compact
65
65
  end
66
66
 
67
67
  def self.from_line(line)
@@ -106,23 +106,6 @@ module WM
106
106
  system "wmctrl", "-i", "-a", window_id
107
107
  end
108
108
 
109
- def maximized?
110
- end
111
-
112
- def maximize!
113
- system "wmctrl", "-i", "-a", window_id
114
- end
115
-
116
-
117
- def unmazimize!
118
- end
119
-
120
- def minimized?
121
- end
122
-
123
- def minimize!
124
- end
125
-
126
109
  #
127
110
  # string is made up of regular text, plus <>'d keypresses
128
111
  # eg: "Hello<Ctrl-T><Ctrl-L><Ctrl-Shift-K><Return>!!!"
@@ -127,26 +127,6 @@ end
127
127
 
128
128
  describe Class do
129
129
 
130
- it "uses" do
131
- module Test1
132
- def test1; :test1; end
133
- end
134
-
135
- module Test2
136
- def test2; :test2; end
137
- end
138
-
139
- Hash.using(Test1).new.test1.should == :test1
140
- Hash.using(Test2).new.test2.should == :test2
141
- h = Hash.using(Test1, Test2).new
142
- h.test1.should == :test1
143
- h.test2.should == :test2
144
-
145
- Hash.using(Test1) do |h|
146
- h.new.test1.should == :test1
147
- end
148
- end
149
-
150
130
  it "traces messages (when $DEBUG is set)" do
151
131
  $DEBUG = true
152
132
 
@@ -166,10 +146,10 @@ describe Class do
166
146
  class ButtTest
167
147
  trace_messages_to :*
168
148
 
169
- def d
149
+ def a
170
150
  end
171
151
 
172
- def e
152
+ def b
173
153
  end
174
154
  end
175
155
 
@@ -197,7 +177,7 @@ describe Numeric do
197
177
  -12983287123.commatize.should == "-12,983,287,123"
198
178
  -12983287123.4411.commatize.should == "-12,983,287,123.4411"
199
179
  1111.1234567.commatize.should == "1,111.1234567"
200
- BigDecimal.new("1111.1234567").commatize.should == "1,111.1234567"
180
+ BigDecimal("1111.1234567").commatize.should == "1,111.1234567"
201
181
  -1234567.1234567.underscorize.should == "-1_234_567.1234567"
202
182
  end
203
183
 
@@ -237,6 +217,11 @@ describe Numeric do
237
217
  32583128.human_size(2).should == "31.07MB"
238
218
  end
239
219
 
220
+ it "temperatures" do
221
+ t = 18.0
222
+ t.to_farenheit.to_celcius.should be_within(0.001).of(t)
223
+ end
224
+
240
225
  end
241
226
 
242
227
 
@@ -795,6 +780,38 @@ describe Enumerable do
795
780
  ps.sort_numerically.map(&:filename).should == proper
796
781
  end
797
782
 
783
+ it "to_csvs and to_tsvs" do
784
+ data = [
785
+ ["1", "2", "3"],
786
+ ["4", "5", "6"],
787
+ ["7", "8", "9", "10"],
788
+ ]
789
+
790
+ hash_data = [
791
+ {a: 1, b: 2, c: 3},
792
+ {a: 4, b: 5, c: 6},
793
+ {a: 7, b: 8, c: 9, d: 10},
794
+ ]
795
+
796
+ class EnumedData
797
+ include Enumerable
798
+ def initialize(data); @data=data; end
799
+ def each(&block); @data.each(&block); end
800
+ end
801
+
802
+ [data, hash_data, EnumedData.new(data)].each do |a|
803
+ str = a.to_csv
804
+ str.each_line.count.should == 3
805
+ str.should_not be_nil
806
+ str["1,2,3"].should_not be_nil
807
+
808
+ str = a.to_tsv
809
+ str.should_not be_nil
810
+ str["1\t2\t3"].should_not be_nil
811
+ end
812
+
813
+ end
814
+
798
815
  end
799
816
 
800
817
 
@@ -1242,6 +1259,16 @@ describe File do
1242
1259
 
1243
1260
  end
1244
1261
 
1262
+ describe ARGV do
1263
+
1264
+ # it "parses args" do
1265
+ # ARGV.clear
1266
+ # ARGV << "-d"
1267
+ # ARGV.parse!
1268
+ # p ARGV.opts
1269
+ # end
1270
+
1271
+ end
1245
1272
 
1246
1273
  describe "Anything" do
1247
1274
 
@@ -1275,5 +1302,15 @@ describe URI do
1275
1302
  (response.size > 0).should == true
1276
1303
  end
1277
1304
 
1305
+ it "params=" do
1306
+ u = "http://butt.cx/?q=1".to_uri
1307
+ u.query.should == "q=1"
1308
+ u.params.should == {"q" => "1"}
1309
+ u.params["q"] = 2
1310
+ u.params["q"].should == 2
1311
+ u.params.should == {"q" => 2}
1312
+ u.query.should == "q=2"
1313
+ end
1314
+
1278
1315
  end
1279
1316
 
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: epitools
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.5.124
4
+ version: 0.5.130
5
5
  platform: ruby
6
6
  authors:
7
7
  - epitron
8
- autorequire:
8
+ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2019-08-05 00:00:00.000000000 Z
11
+ date: 2020-11-16 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rspec
@@ -51,6 +51,7 @@ files:
51
51
  - lib/epitools/clitools.rb
52
52
  - lib/epitools/colored.rb
53
53
  - lib/epitools/core_ext.rb
54
+ - lib/epitools/core_ext/argv.rb
54
55
  - lib/epitools/core_ext/array.rb
55
56
  - lib/epitools/core_ext/class.rb
56
57
  - lib/epitools/core_ext/enumerable.rb
@@ -66,10 +67,12 @@ files:
66
67
  - lib/epitools/core_ext/string.rb
67
68
  - lib/epitools/core_ext/time.rb
68
69
  - lib/epitools/core_ext/truthiness.rb
70
+ - lib/epitools/core_ext/uri.rb
69
71
  - lib/epitools/daemonize.rb
70
72
  - lib/epitools/hexdump.rb
71
73
  - lib/epitools/iter.rb
72
74
  - lib/epitools/its.rb
75
+ - lib/epitools/job_runner.rb
73
76
  - lib/epitools/lcs.rb
74
77
  - lib/epitools/mimemagic.rb
75
78
  - lib/epitools/mimemagic_tables.rb
@@ -124,7 +127,7 @@ homepage: http://github.com/epitron/epitools
124
127
  licenses:
125
128
  - WTFPL
126
129
  metadata: {}
127
- post_install_message:
130
+ post_install_message:
128
131
  rdoc_options: []
129
132
  require_paths:
130
133
  - lib
@@ -139,8 +142,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
139
142
  - !ruby/object:Gem::Version
140
143
  version: '0'
141
144
  requirements: []
142
- rubygems_version: 3.0.4
143
- signing_key:
145
+ rubygems_version: 3.1.4
146
+ signing_key:
144
147
  specification_version: 3
145
148
  summary: Not utils... METILS!
146
149
  test_files: []