epitools 0.4.15 → 0.4.16
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.
- data/README.rdoc +6 -6
- data/VERSION +1 -1
- data/epitools.gemspec +2 -3
- data/lib/epitools.rb +2 -0
- data/lib/epitools/basetypes.rb +36 -14
- data/lib/epitools/browser.rb +1 -1
- data/lib/epitools/browser/cache.rb +3 -0
- data/lib/epitools/browser/mechanize_progressbar.rb +1 -1
- data/lib/epitools/colored.rb +20 -14
- data/lib/epitools/hexdump.rb +1 -1
- data/lib/epitools/path.rb +32 -7
- data/lib/epitools/permutations.rb +13 -2
- data/lib/epitools/pretty_backtrace.rb +2 -27
- data/lib/epitools/rash.rb +8 -7
- data/lib/epitools/sys.rb +1 -1
- data/spec/basetypes_spec.rb +1 -1
- data/spec/path_spec.rb +16 -0
- data/spec/permutations_spec.rb +21 -0
- metadata +2 -3
- data/lib/epitools/http.rb +0 -82
data/README.rdoc
CHANGED
@@ -3,15 +3,15 @@
|
|
3
3
|
Useful miscellaneous improvements for base Ruby objects, plus some extra
|
4
4
|
data structures and handy wrappers.
|
5
5
|
|
6
|
-
Base classess:
|
6
|
+
Base classess have been enhanced: {Enumerable}[http://rdoc.info/gems/epitools/Enumerable], {Hash}[http://rdoc.info/gems/epitools/Hash], {String}[http://rdoc.info/gems/epitools/String], {Array}[http://rdoc.info/gems/epitools/Array], {Object}[http://rdoc.info/gems/epitools/Object], {Integer}[http://rdoc.info/gems/epitools/Integer], etc.
|
7
7
|
|
8
8
|
Extras:
|
9
9
|
|
10
|
-
*
|
11
|
-
*
|
12
|
-
*
|
13
|
-
*
|
14
|
-
* Browser (a fake browser, using mechanize, Progressbar, and CacheDB)
|
10
|
+
* {Colored}[http://rdoc.info/gems/epitools/Colored] (enhanced version of defunkt's colored -- adds ANSI colouring methods to String, eg: #red, #green, #light_blue, etc.)
|
11
|
+
* {Path}[http://rdoc.info/gems/epitools/Path] (a better Pathname)
|
12
|
+
* {Rash}[http://rdoc.info/gems/epitools/Rash] (a hash which can have Regexps as keys, allowing a single (key,value) pair to match many keys.)
|
13
|
+
* {Progressbar}[http://rdoc.info/gems/epitools/Progressbar] (better than the progressbar gem)
|
14
|
+
* {Browser}[http://rdoc.info/gems/epitools/Browser] (a fake browser, using mechanize, Progressbar, and CacheDB)
|
15
15
|
|
16
16
|
== Installing
|
17
17
|
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.4.
|
1
|
+
0.4.16
|
data/epitools.gemspec
CHANGED
@@ -5,11 +5,11 @@
|
|
5
5
|
|
6
6
|
Gem::Specification.new do |s|
|
7
7
|
s.name = %q{epitools}
|
8
|
-
s.version = "0.4.
|
8
|
+
s.version = "0.4.16"
|
9
9
|
|
10
10
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
11
|
s.authors = ["epitron"]
|
12
|
-
s.date = %q{2011-03-
|
12
|
+
s.date = %q{2011-03-15}
|
13
13
|
s.description = %q{Miscellaneous utility libraries to make my life easier.}
|
14
14
|
s.email = %q{chris@ill-logic.com}
|
15
15
|
s.extra_rdoc_files = [
|
@@ -31,7 +31,6 @@ Gem::Specification.new do |s|
|
|
31
31
|
"lib/epitools/clitools.rb",
|
32
32
|
"lib/epitools/colored.rb",
|
33
33
|
"lib/epitools/hexdump.rb",
|
34
|
-
"lib/epitools/http.rb",
|
35
34
|
"lib/epitools/lcs.rb",
|
36
35
|
"lib/epitools/metaclass.rb",
|
37
36
|
"lib/epitools/niceprint.rb",
|
data/lib/epitools.rb
CHANGED
@@ -15,6 +15,7 @@ class Object
|
|
15
15
|
end
|
16
16
|
|
17
17
|
require_wrapper = proc do |mod|
|
18
|
+
#p [:loading, mod]
|
18
19
|
begin
|
19
20
|
require File.join(__DIR__, "epitools", mod)
|
20
21
|
rescue LoadError => e
|
@@ -32,6 +33,7 @@ end
|
|
32
33
|
zopen
|
33
34
|
colored
|
34
35
|
clitools
|
36
|
+
permutations
|
35
37
|
].each do |mod|
|
36
38
|
require_wrapper.call mod
|
37
39
|
end
|
data/lib/epitools/basetypes.rb
CHANGED
@@ -29,10 +29,16 @@ class Numeric
|
|
29
29
|
end
|
30
30
|
|
31
31
|
class Float
|
32
|
+
#
|
33
|
+
# 'true' if the float is 0.0
|
34
|
+
#
|
32
35
|
def blank?; self == 0.0; end
|
33
36
|
end
|
34
37
|
|
35
38
|
class NilClass
|
39
|
+
#
|
40
|
+
# Always 'true'; nil is considered blank.
|
41
|
+
#
|
36
42
|
def blank?; true; end
|
37
43
|
end
|
38
44
|
|
@@ -45,6 +51,9 @@ class String
|
|
45
51
|
strip.match(/^\d+$/) ? true : false
|
46
52
|
end
|
47
53
|
|
54
|
+
#
|
55
|
+
# 'true' if the string's length is 0 (after whitespace has been stripped from the ends)
|
56
|
+
#
|
48
57
|
def blank?
|
49
58
|
strip.size == 0
|
50
59
|
end
|
@@ -91,6 +100,9 @@ end
|
|
91
100
|
|
92
101
|
class Integer
|
93
102
|
|
103
|
+
#
|
104
|
+
# 'true' if the integer is 0
|
105
|
+
#
|
94
106
|
def blank?; self == 0; end
|
95
107
|
|
96
108
|
def to_hex
|
@@ -140,6 +152,9 @@ end
|
|
140
152
|
|
141
153
|
class Array
|
142
154
|
|
155
|
+
#
|
156
|
+
# 'true' if the Array is empty
|
157
|
+
#
|
143
158
|
def blank?; not self.any?; end
|
144
159
|
|
145
160
|
#
|
@@ -191,6 +206,9 @@ end
|
|
191
206
|
|
192
207
|
module Enumerable
|
193
208
|
|
209
|
+
#
|
210
|
+
# 'true' if the Enumerable has no elements
|
211
|
+
#
|
194
212
|
def blank?
|
195
213
|
not self.any?
|
196
214
|
end
|
@@ -378,9 +396,10 @@ module Enumerable
|
|
378
396
|
select.with_index{ |e, i| bitmask[i] == 1 }
|
379
397
|
end
|
380
398
|
end
|
381
|
-
|
399
|
+
|
382
400
|
end
|
383
401
|
|
402
|
+
|
384
403
|
class Object
|
385
404
|
|
386
405
|
#
|
@@ -438,14 +457,14 @@ class Object
|
|
438
457
|
|
439
458
|
#
|
440
459
|
# A decorator that makes any block-accepting method return an
|
441
|
-
#
|
460
|
+
# Enumerator whenever the method is called without a block.
|
442
461
|
#
|
443
462
|
def self.enumerable *meths
|
444
463
|
meths.each do |meth|
|
445
464
|
alias_method "#{meth}_without_enumerator", meth
|
446
465
|
class_eval %{
|
447
466
|
def #{meth}(*args, &block)
|
448
|
-
return
|
467
|
+
return Enum.new(self, #{meth.inspect}, *args, &block) unless block_given?
|
449
468
|
#{meth}_without_enumerator(*args, &block)
|
450
469
|
end
|
451
470
|
}
|
@@ -457,12 +476,15 @@ end
|
|
457
476
|
|
458
477
|
class Hash
|
459
478
|
|
479
|
+
#
|
480
|
+
# 'true' if the Hash has no entries
|
481
|
+
#
|
460
482
|
def blank?
|
461
483
|
not self.any?
|
462
484
|
end
|
463
485
|
|
464
486
|
#
|
465
|
-
# Runs
|
487
|
+
# Runs "remove_blank_values" on self.
|
466
488
|
#
|
467
489
|
def remove_blank_values!
|
468
490
|
delete_if{|k,v| v.blank?}
|
@@ -470,8 +492,8 @@ class Hash
|
|
470
492
|
end
|
471
493
|
|
472
494
|
#
|
473
|
-
# Returns a new Hash where
|
474
|
-
#
|
495
|
+
# Returns a new Hash where blank values have been removed.
|
496
|
+
# (It checks if the value is blank by calling #blank? on it)
|
475
497
|
#
|
476
498
|
def remove_blank_values
|
477
499
|
dup.remove_blank_values!
|
@@ -489,7 +511,8 @@ class Hash
|
|
489
511
|
end
|
490
512
|
|
491
513
|
#
|
492
|
-
#
|
514
|
+
# Transforms the values of the hash by passing them into the supplied
|
515
|
+
# block, and then using the block's result as the new value.
|
493
516
|
#
|
494
517
|
def map_values(&block)
|
495
518
|
dup.map_values!(&block)
|
@@ -507,15 +530,15 @@ class Hash
|
|
507
530
|
end
|
508
531
|
|
509
532
|
#
|
510
|
-
#
|
533
|
+
# Transforms the keys of the hash by passing them into the supplied block,
|
534
|
+
# and then using the blocks result as the new key.
|
511
535
|
#
|
512
536
|
def map_keys(&block)
|
513
537
|
dup.map_keys!(&block)
|
514
538
|
end
|
515
539
|
|
516
540
|
#
|
517
|
-
#
|
518
|
-
# Good for collecting things!
|
541
|
+
# Returns a new Hash whose values default to empty arrays. (Good for collecting things!)
|
519
542
|
#
|
520
543
|
# eg:
|
521
544
|
# Hash.of_arrays[:yays] << "YAY!"
|
@@ -525,8 +548,7 @@ class Hash
|
|
525
548
|
end
|
526
549
|
|
527
550
|
#
|
528
|
-
#
|
529
|
-
# Good for counting things!
|
551
|
+
# Returns a new Hash whose values default to 0. (Good for counting things!)
|
530
552
|
#
|
531
553
|
# eg:
|
532
554
|
# Hash.of_integers[:yays] += 1
|
@@ -572,7 +594,7 @@ protected
|
|
572
594
|
end
|
573
595
|
|
574
596
|
|
575
|
-
class It < BlankSlate
|
597
|
+
class It < BlankSlate # :nodoc:
|
576
598
|
#undef_method( *(instance_methods - ["__id__", "__send__"]) )
|
577
599
|
|
578
600
|
def initialize
|
@@ -593,7 +615,7 @@ class It < BlankSlate
|
|
593
615
|
end
|
594
616
|
end
|
595
617
|
|
596
|
-
class NotWrapper < BlankSlate
|
618
|
+
class NotWrapper < BlankSlate # :nodoc:
|
597
619
|
def initialize(orig)
|
598
620
|
@orig = orig
|
599
621
|
end
|
data/lib/epitools/browser.rb
CHANGED
data/lib/epitools/colored.rb
CHANGED
@@ -1,23 +1,31 @@
|
|
1
1
|
require 'Win32/Console/ANSI' if RUBY_PLATFORM =~ /win32/
|
2
2
|
require 'set'
|
3
3
|
|
4
|
-
|
5
|
-
#
|
6
|
-
#
|
7
|
-
#
|
4
|
+
#
|
5
|
+
# ANSI Colour-coding for terminals that support it.
|
6
|
+
# Originally by defunkt (Chris Wanstrath)
|
7
|
+
#
|
8
|
+
# It extends String with methods that insert terminal codes.
|
9
|
+
#
|
10
|
+
# Examples:
|
11
|
+
#
|
12
|
+
# >> "this is red".red
|
8
13
|
#
|
9
|
-
#
|
14
|
+
# >> "this is red with a blue background (read: ugly)".red_on_blue
|
15
|
+
#
|
16
|
+
# >> "this is light blue".light_blue
|
10
17
|
#
|
11
|
-
#
|
18
|
+
# >> "<yellow>This is using <green>tags</green> to colorize.".colorize
|
12
19
|
#
|
13
|
-
#
|
20
|
+
# >> "this is red with an underline".red.underline
|
21
|
+
#
|
22
|
+
# >> "this is really bold and really blue".bold.blue
|
23
|
+
#
|
24
|
+
# >> Colored.red "This is red" # but this part is mostly untested
|
14
25
|
#
|
15
|
-
# >> Colored.red "This is red" # but this part is mostly untested
|
16
26
|
module Colored
|
17
27
|
extend self
|
18
28
|
|
19
|
-
###########################################################################
|
20
|
-
|
21
29
|
@@is_tty = STDOUT.isatty
|
22
30
|
|
23
31
|
COLORS = {
|
@@ -67,8 +75,6 @@ module Colored
|
|
67
75
|
COLORS.map { |k,v| "bold_#{k}" }
|
68
76
|
)
|
69
77
|
|
70
|
-
###########################################################################
|
71
|
-
|
72
78
|
COLORS.each do |color, value|
|
73
79
|
define_method(color) do
|
74
80
|
colorize(self, :foreground => color)
|
@@ -171,7 +177,8 @@ module Colored
|
|
171
177
|
alias_method :is_tty?, :enabled?
|
172
178
|
|
173
179
|
#
|
174
|
-
# Color commands will always produce colored strings
|
180
|
+
# Color commands will always produce colored strings, regardless
|
181
|
+
# of whether the script is being run in a terminal.
|
175
182
|
#
|
176
183
|
def enable!
|
177
184
|
@@is_tty = true
|
@@ -262,7 +269,6 @@ module Colored
|
|
262
269
|
result
|
263
270
|
end
|
264
271
|
|
265
|
-
|
266
272
|
end unless Object.const_defined? :Colored
|
267
273
|
|
268
274
|
String.send(:include, Colored)
|
data/lib/epitools/hexdump.rb
CHANGED
data/lib/epitools/path.rb
CHANGED
@@ -73,19 +73,26 @@ class Path
|
|
73
73
|
|
74
74
|
|
75
75
|
## getters
|
76
|
-
|
77
|
-
|
76
|
+
|
77
|
+
# The path's directories as an array. (eg: ['usr', 'src', 'linux'])
|
78
|
+
attr_reader :dirs
|
79
|
+
|
80
|
+
# The filename without an extension
|
81
|
+
attr_reader :base
|
78
82
|
|
83
|
+
# The file extension, including the . (eg: ".mp3")
|
84
|
+
attr_reader :ext
|
85
|
+
|
86
|
+
# Joins and returns the full path
|
79
87
|
def path
|
80
|
-
d = dir
|
81
|
-
|
82
|
-
if d
|
83
|
-
File.join(d, (f || "") )
|
88
|
+
if d = dir
|
89
|
+
File.join(d, (filename || "") )
|
84
90
|
else
|
85
91
|
""
|
86
92
|
end
|
87
93
|
end
|
88
94
|
|
95
|
+
# The current directory (with a trailing /)
|
89
96
|
def dir
|
90
97
|
if dirs
|
91
98
|
File::SEPARATOR + File.join(*dirs)
|
@@ -159,7 +166,18 @@ class Path
|
|
159
166
|
self.path <=> other.path
|
160
167
|
end
|
161
168
|
|
162
|
-
|
169
|
+
|
170
|
+
## appending
|
171
|
+
|
172
|
+
#
|
173
|
+
# Path["/etc"]/"passwd" == Path["/etc/passwd"]
|
174
|
+
#
|
175
|
+
def /(other)
|
176
|
+
Path.new( File.join(self, other) )
|
177
|
+
end
|
178
|
+
|
179
|
+
|
180
|
+
## opening/reading files
|
163
181
|
|
164
182
|
def open(mode="rb", &block)
|
165
183
|
if block_given?
|
@@ -174,3 +192,10 @@ class Path
|
|
174
192
|
end
|
175
193
|
|
176
194
|
end
|
195
|
+
|
196
|
+
#
|
197
|
+
# Path("/some/path") is the same as Path["/some/path"]
|
198
|
+
#
|
199
|
+
def Path(*args)
|
200
|
+
Path[*args]
|
201
|
+
end
|
@@ -2,7 +2,7 @@ require 'epitools/basetypes'
|
|
2
2
|
|
3
3
|
class Array
|
4
4
|
|
5
|
-
alias_method :"
|
5
|
+
alias_method :"*_without_permutations", :*
|
6
6
|
|
7
7
|
#
|
8
8
|
# Overloaded * operator.
|
@@ -24,7 +24,7 @@ class Array
|
|
24
24
|
end
|
25
25
|
result
|
26
26
|
else
|
27
|
-
send(:"
|
27
|
+
send(:"*_without_permutations", other)
|
28
28
|
end
|
29
29
|
end
|
30
30
|
|
@@ -35,6 +35,17 @@ class Array
|
|
35
35
|
([self] * exponent).foldl(:*)
|
36
36
|
end
|
37
37
|
|
38
|
+
def all_pairs(reflexive=false)
|
39
|
+
(0...size).each do |a|
|
40
|
+
start = reflexive ? a : a+1
|
41
|
+
(start...size).each do |b|
|
42
|
+
yield self[a], self[b]
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
enumerable :all_pairs
|
48
|
+
|
38
49
|
end
|
39
50
|
|
40
51
|
|
@@ -5,32 +5,7 @@ require 'colorize'
|
|
5
5
|
# TODO: Pick a backtrace format. (Also, add a method to replace default backtracer.)
|
6
6
|
# TODO: This chould be in a class.
|
7
7
|
|
8
|
-
class
|
9
|
-
|
10
|
-
def split_when(&block)
|
11
|
-
|
12
|
-
chunks = []
|
13
|
-
start = 0
|
14
|
-
|
15
|
-
for i in 0...self.size-1
|
16
|
-
|
17
|
-
split_here = yield(self[i], self[i+1])
|
18
|
-
if split_here
|
19
|
-
chunks << self[start..i]
|
20
|
-
start = i+1
|
21
|
-
end
|
22
|
-
|
23
|
-
end
|
24
|
-
|
25
|
-
chunks << self[start..-1]
|
26
|
-
chunks
|
27
|
-
|
28
|
-
end
|
29
|
-
|
30
|
-
end
|
31
|
-
|
32
|
-
|
33
|
-
class Line
|
8
|
+
class Line # :nodoc:
|
34
9
|
|
35
10
|
attr_accessor :path, :num, :meth, :dir, :filename
|
36
11
|
|
@@ -79,7 +54,7 @@ end
|
|
79
54
|
|
80
55
|
|
81
56
|
def color_backtrace_1(lines)
|
82
|
-
groups = lines.
|
57
|
+
groups = lines.split_before { |line,nextline| line.path != nextline.path }
|
83
58
|
for group in groups
|
84
59
|
dir, filename = File.split(group.first.path)
|
85
60
|
puts "#{filename.green} (#{dir.light_white})"
|
data/lib/epitools/rash.rb
CHANGED
@@ -1,5 +1,11 @@
|
|
1
1
|
#
|
2
|
-
# A Regex-queryable Hash
|
2
|
+
# A Regex-queryable Hash.
|
3
|
+
#
|
4
|
+
# Usage:
|
5
|
+
#
|
6
|
+
# greeting = Rash.new( /^Mr./ => "Hello sir!", /^Mrs./ => "Evening, madame." )
|
7
|
+
# greeting["Mr. Steve Austin"] #=> "Hello sir!"
|
8
|
+
# greeting["Mrs. Steve Austin"] #=> "Evening, madame."
|
3
9
|
#
|
4
10
|
class Rash
|
5
11
|
|
@@ -17,7 +23,7 @@ class Rash
|
|
17
23
|
|
18
24
|
def []=(key, value)
|
19
25
|
if key.is_a? Regexp
|
20
|
-
key = normalize_regex(key)
|
26
|
+
#key = normalize_regex(key) # this used to just do: /#{regexp}/
|
21
27
|
@regexes << key
|
22
28
|
end
|
23
29
|
@hash[key] = value
|
@@ -83,10 +89,5 @@ private
|
|
83
89
|
end
|
84
90
|
end
|
85
91
|
|
86
|
-
def normalize_regex(regex)
|
87
|
-
#/^#{regex}$/
|
88
|
-
regex
|
89
|
-
end
|
90
|
-
|
91
92
|
end
|
92
93
|
|
data/lib/epitools/sys.rb
CHANGED
data/spec/basetypes_spec.rb
CHANGED
data/spec/path_spec.rb
CHANGED
@@ -1,3 +1,4 @@
|
|
1
|
+
require 'epitools/permutations'
|
1
2
|
require 'epitools/path'
|
2
3
|
|
3
4
|
describe Path do
|
@@ -101,4 +102,19 @@ describe Path do
|
|
101
102
|
s2[15..-1].should == s1
|
102
103
|
end
|
103
104
|
|
105
|
+
it "makes paths THREE WAYS!" do
|
106
|
+
[
|
107
|
+
Path(__FILE__),
|
108
|
+
Path[__FILE__],
|
109
|
+
Path.new(__FILE__),
|
110
|
+
].all_pairs do |p1, p2|
|
111
|
+
p1.path.should == p2.path
|
112
|
+
end
|
113
|
+
end
|
114
|
+
|
115
|
+
it "appending to paths with /" do
|
116
|
+
( Path['/etc']/'passwd' ).should == Path['/etc/passwd']
|
117
|
+
( Path['/etc']/Path['passwd'] ).should_not == Path['/etc/passwd']
|
118
|
+
end
|
119
|
+
|
104
120
|
end
|
data/spec/permutations_spec.rb
CHANGED
@@ -11,4 +11,25 @@ describe "Permutations" do
|
|
11
11
|
([1,2] ** 2).should == [ [1,1], [1,2], [2,1], [2,2] ]
|
12
12
|
end
|
13
13
|
|
14
|
+
it "all_pairses" do
|
15
|
+
[1,2,3,4].all_pairs.to_a.should == [
|
16
|
+
[1,2],
|
17
|
+
[1,3],
|
18
|
+
[1,4],
|
19
|
+
[2,3],
|
20
|
+
[2,4],
|
21
|
+
[3,4],
|
22
|
+
]
|
23
|
+
|
24
|
+
# reflexive
|
25
|
+
[1,2,3].all_pairs(true).to_a.should == [
|
26
|
+
[1,1],
|
27
|
+
[1,2],
|
28
|
+
[1,3],
|
29
|
+
[2,2],
|
30
|
+
[2,3],
|
31
|
+
[3,3],
|
32
|
+
]
|
33
|
+
end
|
34
|
+
|
14
35
|
end
|
metadata
CHANGED
@@ -2,7 +2,7 @@
|
|
2
2
|
name: epitools
|
3
3
|
version: !ruby/object:Gem::Version
|
4
4
|
prerelease:
|
5
|
-
version: 0.4.
|
5
|
+
version: 0.4.16
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
8
8
|
- epitron
|
@@ -10,7 +10,7 @@ autorequire:
|
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
12
|
|
13
|
-
date: 2011-03-
|
13
|
+
date: 2011-03-15 00:00:00 -04:00
|
14
14
|
default_executable:
|
15
15
|
dependencies:
|
16
16
|
- !ruby/object:Gem::Dependency
|
@@ -70,7 +70,6 @@ files:
|
|
70
70
|
- lib/epitools/clitools.rb
|
71
71
|
- lib/epitools/colored.rb
|
72
72
|
- lib/epitools/hexdump.rb
|
73
|
-
- lib/epitools/http.rb
|
74
73
|
- lib/epitools/lcs.rb
|
75
74
|
- lib/epitools/metaclass.rb
|
76
75
|
- lib/epitools/niceprint.rb
|
data/lib/epitools/http.rb
DELETED
@@ -1,82 +0,0 @@
|
|
1
|
-
require 'net/http'
|
2
|
-
require 'uri'
|
3
|
-
|
4
|
-
# TODO: what?? this needs to be a class.
|
5
|
-
|
6
|
-
class PartialPage < Exception
|
7
|
-
attr_accessor :data
|
8
|
-
end
|
9
|
-
|
10
|
-
def read_data_from_response(response, amount)
|
11
|
-
|
12
|
-
amount_read = 0
|
13
|
-
chunks = []
|
14
|
-
|
15
|
-
begin
|
16
|
-
response.read_body do |chunk| # read body now
|
17
|
-
|
18
|
-
amount_read += chunk.length
|
19
|
-
|
20
|
-
if amount_read > amount
|
21
|
-
amount_of_overflow = amount_read - amount
|
22
|
-
chunk = chunk[0...-amount_of_overflow]
|
23
|
-
end
|
24
|
-
|
25
|
-
chunks << chunk
|
26
|
-
|
27
|
-
if amount_read >= amount
|
28
|
-
raise PartialPage.new chunks.join('')
|
29
|
-
end
|
30
|
-
|
31
|
-
end
|
32
|
-
end
|
33
|
-
|
34
|
-
end
|
35
|
-
|
36
|
-
|
37
|
-
def http_get_streaming(url = URI.parse("http://epi.is-a-geek.net/files/Mr.%20Show%20-%20Civil%20War%20Re-enactment.avi"))
|
38
|
-
|
39
|
-
#headers = {'User-Agent' => "Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.8.0.1) Gecko/20060111 Firefox/1.5.0.1"}
|
40
|
-
headers = nil
|
41
|
-
|
42
|
-
Net::HTTP.start(url.host, url.port) do |http|
|
43
|
-
# using block
|
44
|
-
response = http.request_get(url.path, headers) {|response|
|
45
|
-
puts "Response: #{response.inspect}"
|
46
|
-
puts "to hash: #{response.to_hash.inspect}"
|
47
|
-
|
48
|
-
begin
|
49
|
-
read_data_from_response(response, 500)
|
50
|
-
rescue PartialPage => p
|
51
|
-
puts "GOT THE PARTIAL PAGE!"
|
52
|
-
data = p.data
|
53
|
-
end
|
54
|
-
|
55
|
-
puts
|
56
|
-
puts "===========first 500 bytes================="
|
57
|
-
puts data
|
58
|
-
}
|
59
|
-
end
|
60
|
-
|
61
|
-
end
|
62
|
-
|
63
|
-
|
64
|
-
# TODO: Remove RIO dependancy.
|
65
|
-
|
66
|
-
def http_get_cached(url)
|
67
|
-
require 'digest/md5'
|
68
|
-
require 'rio'
|
69
|
-
|
70
|
-
tempdir = ENV['TEMP']
|
71
|
-
cachefile = rio(tempdir, "cached_url_#{Digest::SHA1.hexdigest(url)}")
|
72
|
-
|
73
|
-
if cachefile.exist?
|
74
|
-
data = rio(cachefile).read
|
75
|
-
else
|
76
|
-
data = rio(url).read
|
77
|
-
rio(cachefile).binmode < data
|
78
|
-
end
|
79
|
-
|
80
|
-
data
|
81
|
-
end
|
82
|
-
|