epitools 0.5.129 → 0.5.134
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/VERSION +1 -1
- data/lib/epitools/autoloads.rb +4 -1
- data/lib/epitools/clitools.rb +10 -0
- data/lib/epitools/core_ext/class.rb +5 -19
- data/lib/epitools/core_ext/numbers.rb +27 -8
- data/lib/epitools/core_ext/truthiness.rb +1 -2
- data/lib/epitools/core_ext/uri.rb +29 -15
- data/lib/epitools/gem_ext/oga.rb +31 -0
- data/lib/epitools/job_runner.rb +22 -4
- data/lib/epitools/numwords.rb +1 -1
- data/lib/epitools/path.rb +20 -11
- data/lib/epitools/sys.rb +1 -0
- data/spec/core_ext_spec.rb +20 -29
- metadata +4 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 2aefbc7936ad578ce3f2ae8806e67be1815f4e2a55ddf43a915bcdaa0ca9f68a
|
4
|
+
data.tar.gz: 6d09789e434d7cda9b66e25ecf1ebf9db61d6236f1342b83743330e42d9ab09f
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 4c98a36281937b7dd6e8f6154af595f5153d51803da0587eafc1a8dec26c96adac899e73c9ef49157b8fadcdf01fb845b60095d9ceb9722b5107c0eeaf6f8550
|
7
|
+
data.tar.gz: ccf09c13ef7df31e8d6994ba1c5550dc606fd61ac909c14f00c53788160a69cb53e7c425156a373732f4fbc7e021bde12c27e850be0ca1cf4735b86d9cf01285
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.5.
|
1
|
+
0.5.134
|
data/lib/epitools/autoloads.rb
CHANGED
@@ -98,8 +98,11 @@ autoreq :Mechanize, 'mechanize'
|
|
98
98
|
autoreq :HTTP, 'http'
|
99
99
|
|
100
100
|
autoreq :Nokogiri, 'nokogiri'
|
101
|
-
autoreq :Oga, 'oga'
|
102
101
|
autoreq :Ox, 'ox'
|
102
|
+
autoreq :Oga do
|
103
|
+
require 'oga'
|
104
|
+
require 'epitools/gem_ext/oga'
|
105
|
+
end
|
103
106
|
|
104
107
|
autoreq :ANSI, 'ansi'
|
105
108
|
|
data/lib/epitools/clitools.rb
CHANGED
@@ -247,3 +247,13 @@ end
|
|
247
247
|
def curl_json(url)
|
248
248
|
JSON.parse(curl(url))
|
249
249
|
end
|
250
|
+
|
251
|
+
def cached_curl(url)
|
252
|
+
cache = "/tmp/curl-#{url.sha1}.cache"
|
253
|
+
if File.exist?(cache)
|
254
|
+
$stderr.puts "cached! => #{cache}"
|
255
|
+
else
|
256
|
+
File.write(cache, curl(url))
|
257
|
+
end
|
258
|
+
File.read(cache)
|
259
|
+
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
|
-
|
39
|
-
|
40
|
-
$stderr.puts "[*] #{parent}##{meth}(#{
|
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,5 +1,5 @@
|
|
1
1
|
|
2
|
-
Number = Numeric # "obj.is_a? Number"
|
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
|
-
[
|
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
|
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,
|
217
|
-
hours,
|
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,
|
233
|
-
hours,
|
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,22 @@ 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
|
+
|
256
|
+
def to_lbs
|
257
|
+
self / 0.45359237
|
258
|
+
end
|
259
|
+
|
260
|
+
def to_kg
|
261
|
+
self * 0.45359237
|
262
|
+
end
|
263
|
+
|
246
264
|
end
|
247
265
|
|
248
266
|
|
@@ -442,7 +460,8 @@ end
|
|
442
460
|
class Prime
|
443
461
|
|
444
462
|
#
|
445
|
-
# Return an array of prime numbers within the specified range
|
463
|
+
# Return an array of prime numbers within the specified range.
|
464
|
+
# (It still has to generate all the primes less than the lower bound, so, yeah... be warned.)
|
446
465
|
#
|
447
466
|
def [](range)
|
448
467
|
ubound = range.end
|
@@ -130,10 +130,9 @@ class String
|
|
130
130
|
#
|
131
131
|
# Is there anything in the string? (ignoring whitespace/newlines)
|
132
132
|
#
|
133
|
-
def
|
133
|
+
def present?
|
134
134
|
not blank?
|
135
135
|
end
|
136
|
-
alias_method :present?, :any?
|
137
136
|
|
138
137
|
#
|
139
138
|
# Does this string contain something that means roughly "true"?
|
@@ -1,37 +1,47 @@
|
|
1
1
|
require 'uri'
|
2
2
|
|
3
|
-
|
3
|
+
class URI::Generic
|
4
4
|
|
5
5
|
#
|
6
|
-
#
|
6
|
+
# Get the query string
|
7
7
|
#
|
8
|
-
def
|
9
|
-
|
8
|
+
def query
|
9
|
+
params.to_query
|
10
10
|
end
|
11
11
|
|
12
12
|
#
|
13
|
-
#
|
13
|
+
# Set the query string
|
14
14
|
#
|
15
|
-
def
|
16
|
-
|
15
|
+
def query=(new_query)
|
16
|
+
@params = new_query&.to_params
|
17
|
+
@query = new_query
|
17
18
|
end
|
18
19
|
|
19
20
|
#
|
20
|
-
#
|
21
|
+
# Return a Hash of the variables in the query string
|
21
22
|
#
|
22
|
-
def
|
23
|
-
|
24
|
-
current[key] = value
|
25
|
-
self.query = current.to_query
|
23
|
+
def params
|
24
|
+
@params ||= (@query ? @query.to_params : {})
|
26
25
|
end
|
27
26
|
|
28
27
|
#
|
29
|
-
#
|
28
|
+
# Update all the params at once
|
30
29
|
#
|
31
|
-
def
|
32
|
-
|
30
|
+
def params=(new_params)
|
31
|
+
# self.query = new_params.to_params
|
32
|
+
raise "params must be a Hash" unless new_params.is_a? Hash
|
33
|
+
@params = new_params
|
33
34
|
end
|
34
35
|
|
36
|
+
# #
|
37
|
+
# # Update one URI parameter
|
38
|
+
# #
|
39
|
+
# def set_param(key, value)
|
40
|
+
# current = params
|
41
|
+
# current[key] = value
|
42
|
+
# self.query = current.to_query
|
43
|
+
# end
|
44
|
+
|
35
45
|
#
|
36
46
|
# URIs *are* strings, dammit!
|
37
47
|
#
|
@@ -39,6 +49,10 @@ module URI
|
|
39
49
|
to_s
|
40
50
|
end
|
41
51
|
|
52
|
+
end
|
53
|
+
|
54
|
+
module URI
|
55
|
+
|
42
56
|
#
|
43
57
|
# Default user agent for the 'get' method
|
44
58
|
#
|
@@ -0,0 +1,31 @@
|
|
1
|
+
|
2
|
+
module Oga
|
3
|
+
module XML
|
4
|
+
# Serialize this node to HAML
|
5
|
+
module ElementToHAML
|
6
|
+
def to_haml
|
7
|
+
require 'html2haml'
|
8
|
+
require 'html2haml/html'
|
9
|
+
Html2haml::HTML.new(to_xml, {}).render.rstrip
|
10
|
+
end
|
11
|
+
alias_method :haml, :to_haml
|
12
|
+
|
13
|
+
def pretty
|
14
|
+
require 'coderay'
|
15
|
+
puts CodeRay.scan(haml, :haml).term
|
16
|
+
end
|
17
|
+
#alias_method :pp, :pretty
|
18
|
+
end
|
19
|
+
|
20
|
+
module PrettyNodeSet
|
21
|
+
def pretty
|
22
|
+
require 'coderay'
|
23
|
+
lesspipe(wrap: true) { |less| each { |node| less.puts CodeRay.scan(node.to_haml, :haml).term; less.puts; less.puts } }
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
Oga::XML::Element.include Oga::XML::ElementToHAML
|
31
|
+
Oga::XML::NodeSet.include Oga::XML::PrettyNodeSet
|
data/lib/epitools/job_runner.rb
CHANGED
@@ -26,11 +26,12 @@
|
|
26
26
|
# end
|
27
27
|
#
|
28
28
|
class JobRunner
|
29
|
-
def initialize(*blocks)
|
29
|
+
def initialize(*blocks, debug: false)
|
30
30
|
@threads = []
|
31
31
|
@results = Thread::Queue.new
|
32
32
|
@jobs = []
|
33
33
|
@started = false
|
34
|
+
@debug = debug
|
34
35
|
|
35
36
|
if blocks.any?
|
36
37
|
blocks.each { |block| add &block }
|
@@ -39,20 +40,37 @@ class JobRunner
|
|
39
40
|
end
|
40
41
|
end
|
41
42
|
|
43
|
+
def dmsg(msg)
|
44
|
+
puts "[#{Time.now}] #{msg}" if @debug
|
45
|
+
end
|
46
|
+
|
42
47
|
def add(&block)
|
48
|
+
dmsg("added job #{block}")
|
43
49
|
@jobs << block
|
44
50
|
end
|
45
51
|
|
46
52
|
def reap!
|
47
|
-
|
53
|
+
if @threads.any?
|
54
|
+
dmsg("reaping #{@threads.size} threads")
|
55
|
+
@threads.delete_if { |t| not t.alive? }
|
56
|
+
else
|
57
|
+
dmsg("reap failed: no threads")
|
58
|
+
end
|
48
59
|
end
|
49
60
|
|
50
61
|
def go!
|
51
|
-
|
62
|
+
if @started
|
63
|
+
raise "Error: already started"
|
64
|
+
else
|
65
|
+
dmsg("starting #{@threads.size} jobs")
|
66
|
+
end
|
67
|
+
|
52
68
|
@started = true
|
53
69
|
@jobs.each do |job|
|
70
|
+
dmsg("adding #{job}")
|
54
71
|
@threads << Thread.new do
|
55
72
|
@results << job.call
|
73
|
+
dmsg("job #{job} complete")
|
56
74
|
end
|
57
75
|
end
|
58
76
|
end
|
@@ -72,7 +90,7 @@ end
|
|
72
90
|
|
73
91
|
|
74
92
|
if __FILE__ == $0
|
75
|
-
JobRunner.new do |jr|
|
93
|
+
JobRunner.new(debug: true) do |jr|
|
76
94
|
jr.add { 3 }
|
77
95
|
jr.add { sleep 0.1; 2 }
|
78
96
|
jr.add { sleep 0.2; 1 }
|
data/lib/epitools/numwords.rb
CHANGED
data/lib/epitools/path.rb
CHANGED
@@ -119,11 +119,20 @@ class Path
|
|
119
119
|
# The file extension, including the . (eg: ".mp3")
|
120
120
|
attr_reader :ext
|
121
121
|
|
122
|
+
URI_RE = %r{^[a-z\-]+://}i
|
122
123
|
|
123
124
|
###############################################################################
|
124
125
|
# Initializers
|
125
126
|
###############################################################################
|
126
127
|
|
128
|
+
def self.new(*args)
|
129
|
+
if args.first =~ URI_RE and self != Path::URI
|
130
|
+
Path::URI.new(args.first)
|
131
|
+
else
|
132
|
+
super(*args)
|
133
|
+
end
|
134
|
+
end
|
135
|
+
|
127
136
|
def initialize(newpath, hints={})
|
128
137
|
send("path=", newpath, hints)
|
129
138
|
|
@@ -156,8 +165,8 @@ class Path
|
|
156
165
|
path
|
157
166
|
when String
|
158
167
|
|
159
|
-
if path =~
|
160
|
-
Path
|
168
|
+
if path =~ URI_RE
|
169
|
+
Path.new(path)
|
161
170
|
|
162
171
|
else
|
163
172
|
# TODO: highlight backgrounds of codeblocks to show indent level & put boxes (or rules?) around (between?) double-spaced regions
|
@@ -186,7 +195,7 @@ class Path
|
|
186
195
|
# Note: The `hints` parameter contains options so `path=` doesn't have to touch the filesytem as much.
|
187
196
|
#
|
188
197
|
def path=(newpath, hints={})
|
189
|
-
if hints[:type] or File.
|
198
|
+
if hints[:type] or File.exist? newpath
|
190
199
|
if hints[:type] == :dir or File.directory? newpath
|
191
200
|
self.dir = newpath
|
192
201
|
else
|
@@ -357,7 +366,7 @@ class Path
|
|
357
366
|
###############################################################################
|
358
367
|
|
359
368
|
def exists?
|
360
|
-
File.
|
369
|
+
File.exist? path
|
361
370
|
end
|
362
371
|
|
363
372
|
def size
|
@@ -430,7 +439,7 @@ class Path
|
|
430
439
|
end
|
431
440
|
|
432
441
|
def broken_symlink?
|
433
|
-
File.symlink?(path) and not File.
|
442
|
+
File.symlink?(path) and not File.exist?(path)
|
434
443
|
end
|
435
444
|
|
436
445
|
def symlink_target
|
@@ -930,7 +939,7 @@ class Path
|
|
930
939
|
|
931
940
|
# Parse the file as CSV
|
932
941
|
def read_csv(io=self.io, opts={})
|
933
|
-
|
942
|
+
CSV.new(io.read, **opts).each
|
934
943
|
end
|
935
944
|
alias_method :from_csv, :read_csv
|
936
945
|
|
@@ -1638,9 +1647,9 @@ class Path::URI < Path
|
|
1638
1647
|
#
|
1639
1648
|
# When this is: http://host.com:port/path/filename.ext?param1=value1¶m2=value2&...
|
1640
1649
|
#
|
1641
|
-
def to_s
|
1642
|
-
|
1643
|
-
end
|
1650
|
+
def to_s; uri.to_s; end
|
1651
|
+
def to_path; to_s; end
|
1652
|
+
def to_str; to_s; end
|
1644
1653
|
|
1645
1654
|
def inspect
|
1646
1655
|
"#<Path::URI:#{to_s}>"
|
@@ -1693,9 +1702,9 @@ class Path::URI < Path
|
|
1693
1702
|
def open(mode="r", &block)
|
1694
1703
|
require 'open-uri'
|
1695
1704
|
if block_given?
|
1696
|
-
|
1705
|
+
::URI.open(to_s, mode, &block)
|
1697
1706
|
else
|
1698
|
-
|
1707
|
+
::URI.open(to_s, mode)
|
1699
1708
|
end
|
1700
1709
|
end
|
1701
1710
|
|
data/lib/epitools/sys.rb
CHANGED
data/spec/core_ext_spec.rb
CHANGED
@@ -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
|
149
|
+
def a
|
170
150
|
end
|
171
151
|
|
172
|
-
def
|
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
|
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
|
|
@@ -1311,18 +1296,24 @@ describe URI do
|
|
1311
1296
|
uri.params.should == opts
|
1312
1297
|
end
|
1313
1298
|
|
1314
|
-
it "gets" do
|
1315
|
-
|
1316
|
-
|
1317
|
-
|
1318
|
-
end
|
1299
|
+
# it "gets" do
|
1300
|
+
# response = URI("http://google.com/").get
|
1301
|
+
# response.body.size
|
1302
|
+
# (response.size > 0).should == true
|
1303
|
+
# end
|
1319
1304
|
|
1320
1305
|
it "params=" do
|
1321
|
-
u = "http://butt.
|
1306
|
+
u = "http://butt.cx/?q=1".to_uri
|
1322
1307
|
u.query.should == "q=1"
|
1308
|
+
u.params.should == {"q" => "1"}
|
1323
1309
|
u.params["q"] = 2
|
1324
1310
|
u.params["q"].should == 2
|
1311
|
+
u.params.should == {"q" => 2}
|
1325
1312
|
u.query.should == "q=2"
|
1313
|
+
|
1314
|
+
subbed = u.with(query: u.params.reject{|k,v| u.params.keys.include? 'q' }.to_query)
|
1315
|
+
subbed.params.should == {}
|
1316
|
+
subbed.query.should == ""
|
1326
1317
|
end
|
1327
1318
|
|
1328
1319
|
end
|
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.
|
4
|
+
version: 0.5.134
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- epitron
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2021-10-31 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rspec
|
@@ -69,6 +69,7 @@ files:
|
|
69
69
|
- lib/epitools/core_ext/truthiness.rb
|
70
70
|
- lib/epitools/core_ext/uri.rb
|
71
71
|
- lib/epitools/daemonize.rb
|
72
|
+
- lib/epitools/gem_ext/oga.rb
|
72
73
|
- lib/epitools/hexdump.rb
|
73
74
|
- lib/epitools/iter.rb
|
74
75
|
- lib/epitools/its.rb
|
@@ -142,7 +143,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
142
143
|
- !ruby/object:Gem::Version
|
143
144
|
version: '0'
|
144
145
|
requirements: []
|
145
|
-
rubygems_version: 3.
|
146
|
+
rubygems_version: 3.2.21
|
146
147
|
signing_key:
|
147
148
|
specification_version: 3
|
148
149
|
summary: Not utils... METILS!
|