epitools 0.4.15 → 0.4.16

Sign up to get free protection for your applications and to get access to all the features.
@@ -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: Object, Enumerable, Hash, String, Array, Integer, etc.
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
- * Path (a better Pathname)
11
- * Rash (a hash which can have Regexps as keys, allowing a single (key,value) pair to match many keys.)
12
- * Progressbar (better than the progressbar gem)
13
- * Colored (enhanced version of defunkt's colored -- adds ANSI colouring methods to String, eg: #red, #green, #light_blue, etc.)
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.15
1
+ 0.4.16
@@ -5,11 +5,11 @@
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = %q{epitools}
8
- s.version = "0.4.15"
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-14}
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",
@@ -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
@@ -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
- # Enumerable::Enumerator whenever the method is called without a block.
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 Enumerable::Enumerator.new(self, #{meth.inspect}, *args, &block) unless block_given?
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 remove_blank_lines on self.
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 all elements whose values are "blank?" (eg: "", [], nil)
474
- # have been eliminated.
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
- # Returns a Hash whsoe values have been transformed by the block.
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
- # Returns a new Hash whose keys have been transformed by the block.
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
- # Creates an new Hash whose missing items default to [].
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
- # Creates an new Hash whose missing items default to values of 0.
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
@@ -8,7 +8,7 @@ require 'epitools/browser/mechanize_progressbar'
8
8
 
9
9
  # TODO: Make socksify optional (eg: if proxy is specified)
10
10
  #require 'socksify'
11
- class SOCKSError < Exception; end
11
+ class SOCKSError < Exception; end # :nodoc:
12
12
 
13
13
  # TODO: Put options here.
14
14
  =begin
@@ -1,6 +1,9 @@
1
1
  require 'mechanize'
2
2
  require 'sqlite3'
3
3
 
4
+ #
5
+ # Emit a quick debug message (only if $DEBUG is true)
6
+ #
4
7
  def dmsg(msg)
5
8
 
6
9
  if $DEBUG
@@ -5,7 +5,7 @@ require 'epitools/progressbar'
5
5
  #
6
6
  # (Displays a progress bar whenever an url is retrieved.)
7
7
  #
8
- class Mechanize
8
+ class Mechanize # :nodoc: all
9
9
  class Chain
10
10
  class ResponseReader
11
11
  include Mechanize::Handler
@@ -1,23 +1,31 @@
1
1
  require 'Win32/Console/ANSI' if RUBY_PLATFORM =~ /win32/
2
2
  require 'set'
3
3
 
4
- ##
5
- # cute.
6
- #
7
- # >> "this is red".red
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
- # >> "this is red with a blue background (read: ugly)".red_on_blue
14
+ # >> "this is red with a blue background (read: ugly)".red_on_blue
15
+ #
16
+ # >> "this is light blue".light_blue
10
17
  #
11
- # >> "this is red with an underline".red.underline
18
+ # >> "<yellow>This is using <green>tags</green> to colorize.".colorize
12
19
  #
13
- # >> "this is really bold and really blue".bold.blue
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)
@@ -1,4 +1,4 @@
1
- %w[rubygems colorize].each{|r| require r}
1
+ require 'colored'
2
2
 
3
3
  ASCII_PRINTABLE = (33..126)
4
4
 
@@ -73,19 +73,26 @@ class Path
73
73
 
74
74
 
75
75
  ## getters
76
-
77
- attr_reader :dirs, :base, :ext
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
- f = filename
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
- ## opening/reading
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 :"original_*_for_cartesian_*", :*
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(:"original_*_for_cartesian_*", other)
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 Array
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.split_when { |line,nextline| line.path != nextline.path }
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})"
@@ -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
 
@@ -2,7 +2,7 @@
2
2
  # Cross-platform operating system functions.
3
3
  # Includes: process listing, platform detection, etc.
4
4
  #
5
- require 'metaclass'
5
+ require 'epitools/metaclass'
6
6
 
7
7
  module Sys
8
8
 
@@ -208,7 +208,7 @@ describe Enumerable do
208
208
  it "powersets" do
209
209
  [1,2,3].powerset.should == [[], [1], [2], [1, 2], [3], [1, 3], [2, 3], [1, 2, 3]]
210
210
  end
211
-
211
+
212
212
  end
213
213
 
214
214
  describe Hash do
@@ -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
@@ -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.15
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-14 00:00:00 -04:00
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
@@ -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
-