epitools 0.5.1 → 0.5.2

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.
@@ -0,0 +1,16 @@
1
+ # A sample Guardfile
2
+ # More info at https://github.com/guard/guard#readme
3
+
4
+ #guard 'spork', :wait => 50 do
5
+ # watch('Gemfile')
6
+ # watch('Gemfile.lock')
7
+ # watch('spec/spec_helper.rb')
8
+ #end
9
+
10
+ guard :rspec, :version => 2, :cli => "--color", :bundler => false, :all_after_pass => false, :all_on_start => false, :keep_failed => false do
11
+ #guard 'rspec', :version => 2 do
12
+ watch(%r{^spec/.+_spec\.rb$})
13
+ watch(%r{^lib/epitools/(.+)\.rb$}) { |m| "spec/#{m[1]}_spec.rb" }
14
+ watch('spec/spec_helper.rb') { "spec" }
15
+ end
16
+
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.5.1
1
+ 0.5.2
@@ -5,11 +5,11 @@
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = "epitools"
8
- s.version = "0.5.1"
8
+ s.version = "0.5.2"
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 = "2011-11-23"
12
+ s.date = "2012-04-05"
13
13
  s.description = "Miscellaneous utility libraries to make my life easier."
14
14
  s.email = "chris@ill-logic.com"
15
15
  s.extra_rdoc_files = [
@@ -19,6 +19,7 @@ Gem::Specification.new do |s|
19
19
  ]
20
20
  s.files = [
21
21
  ".document",
22
+ "Guardfile",
22
23
  "LICENSE",
23
24
  "README.rdoc",
24
25
  "Rakefile",
@@ -27,12 +28,19 @@ Gem::Specification.new do |s|
27
28
  "epitools.gemspec",
28
29
  "lib/epitools.rb",
29
30
  "lib/epitools/autoloads.rb",
30
- "lib/epitools/basetypes.rb",
31
31
  "lib/epitools/browser.rb",
32
32
  "lib/epitools/browser/cache.rb",
33
33
  "lib/epitools/browser/mechanize_progressbar.rb",
34
34
  "lib/epitools/clitools.rb",
35
35
  "lib/epitools/colored.rb",
36
+ "lib/epitools/core_ext.rb",
37
+ "lib/epitools/core_ext/array.rb",
38
+ "lib/epitools/core_ext/enumerable.rb",
39
+ "lib/epitools/core_ext/hash.rb",
40
+ "lib/epitools/core_ext/numbers.rb",
41
+ "lib/epitools/core_ext/object.rb",
42
+ "lib/epitools/core_ext/string.rb",
43
+ "lib/epitools/core_ext/truthiness.rb",
36
44
  "lib/epitools/ezdb.rb",
37
45
  "lib/epitools/hexdump.rb",
38
46
  "lib/epitools/iter.rb",
@@ -49,16 +57,15 @@ Gem::Specification.new do |s|
49
57
  "lib/epitools/rails.rb",
50
58
  "lib/epitools/rash.rb",
51
59
  "lib/epitools/ratio.rb",
52
- "lib/epitools/string_to_proc.rb",
53
60
  "lib/epitools/sys.rb",
54
61
  "lib/epitools/term.rb",
55
62
  "lib/epitools/trie.rb",
56
63
  "lib/epitools/zopen.rb",
57
64
  "spec/autoreq_spec.rb",
58
- "spec/basetypes_spec.rb",
59
65
  "spec/browser_spec.rb",
60
66
  "spec/clitools_spec.rb",
61
67
  "spec/colored_spec.rb",
68
+ "spec/core_ext_spec.rb",
62
69
  "spec/ezdb_spec.rb",
63
70
  "spec/iter_spec.rb",
64
71
  "spec/lcs_spec.rb",
@@ -76,7 +83,7 @@ Gem::Specification.new do |s|
76
83
  s.homepage = "http://github.com/epitron/epitools"
77
84
  s.licenses = ["WTFPL"]
78
85
  s.require_paths = ["lib"]
79
- s.rubygems_version = "1.8.10"
86
+ s.rubygems_version = "1.8.21"
80
87
  s.summary = "NOT UTILS... METILS!"
81
88
 
82
89
  if s.respond_to? :specification_version then
@@ -35,20 +35,63 @@ class Object
35
35
  Module.autoreqs[const] = path
36
36
  end
37
37
  end
38
+
39
+ #
40
+ # Remove an object, method, constant, etc.
41
+ #
42
+ def del(x)
43
+ case x
44
+ when String
45
+ del(x.to_sym)
46
+ when Class, Module
47
+ Object.send(:remove_const, x.name)
48
+ when Method
49
+ x.owner.send(:undef_method, x.name)
50
+ when Symbol
51
+ if Object.const_get(x)
52
+ Object.send(:remove_const, x)
53
+ elsif method(x)
54
+ undef_method x
55
+ end
56
+ else
57
+ raise "Error: don't know how to 'del #{x.inspect}'"
58
+ end
59
+ end
38
60
 
61
+ # The hidden singleton lurks behind everyone
62
+ def metaclass
63
+ class << self
64
+ self
65
+ end
66
+ end
67
+
68
+ def meta_eval &blk
69
+ metaclass.instance_eval &blk
70
+ end
71
+
72
+ # Adds methods to a metaclass
73
+ def meta_def name, &blk
74
+ meta_eval { define_method name, &blk }
75
+ end
76
+
77
+ # Defines an instance method within a class
78
+ def class_def name, &blk
79
+ class_eval { define_method name, &blk }
80
+ end
81
+
39
82
  end
40
83
 
41
84
  #
42
- # Patch 'Module#const_missing' to support 'autoreq'
85
+ # Patch 'Module#const_missing' to support 'autoreq' (which can autoload gems)
43
86
  #
44
87
  class Module
45
88
 
46
- @@autoreq_searching_for = nil
89
+ @@autoreq_is_searching_for = nil
47
90
 
48
91
  alias const_missing_without_autoreq const_missing
49
92
 
50
93
  def const_missing(const)
51
- return if const == @@autoreq_searching_for
94
+ return if const == @@autoreq_is_searching_for
52
95
 
53
96
  if thing = autoreqs[const]
54
97
  case thing
@@ -61,7 +104,7 @@ class Module
61
104
  end
62
105
  end
63
106
 
64
- @@autoreq_searching_for = const
107
+ @@autoreq_is_searching_for = const
65
108
  const_get(const) || const_missing_without_autoreq(const)
66
109
  end
67
110
 
@@ -87,8 +130,7 @@ end
87
130
  #
88
131
  %w[
89
132
  autoloads
90
- basetypes
91
- string_to_proc
133
+ core_ext
92
134
  zopen
93
135
  colored
94
136
  clitools
@@ -4,7 +4,6 @@ autoload :URI, 'uri'
4
4
  autoload :CGI, 'cgi'
5
5
  autoload :Base64, 'base64'
6
6
  autoload :JSON, 'json'
7
- autoload :YAML, 'yaml'
8
7
  autoload :Zlib, 'zlib'
9
8
  autoload :FileUtils, 'fileutils'
10
9
  autoload :Tempfile, 'tempfile'
@@ -14,8 +13,18 @@ autoload :Curses, 'curses'
14
13
  autoload :DateTime, 'date'
15
14
  autoload :Date, 'date'
16
15
  autoload :Open3, 'open3'
16
+ autoload :Timeout, 'timeout'
17
+ autoload :Find, 'find'
18
+ autoload :Benchmark, 'benchmark'
17
19
  #autoload :DelegateClass, 'delegate'
18
20
 
21
+ # YAML is sometimes loaded improperly.
22
+ if defined? YAML and not defined? YAML.parse
23
+ del YAML # remove the existing module
24
+ end
25
+
26
+ autoload :YAML, 'yaml'
27
+
19
28
  if RUBY_VERSION["1.8.7"]
20
29
  autoload :Prime, 'mathn'
21
30
  else
@@ -41,5 +50,7 @@ autoload :MimeMagic, 'epitools/mimemagic'
41
50
  autoload :Term, 'epitools/term'
42
51
  autoload :Iter, 'epitools/iter'
43
52
 
44
- ## Gems
45
- autoreq :ANSI, 'ansi'
53
+ ## Gems (common)
54
+ autoreq :Nokogiri, 'nokogiri'
55
+ autoreq :ANSI, 'ansi'
56
+ autoreq :BSON, 'bson'
@@ -140,6 +140,8 @@ class Browser
140
140
  puts "[ GET #{url} (using cache: #{use_cache}) ]"
141
141
 
142
142
  delay unless cached_already
143
+ max_retries = 4
144
+ retries = 0
143
145
 
144
146
  begin
145
147
 
@@ -154,9 +156,14 @@ class Browser
154
156
  puts
155
157
 
156
158
  rescue Net::HTTPBadResponse, Errno::ECONNRESET, SocketError, Timeout::Error, SOCKSError => e
159
+ raise if e.message == "getaddrinfo: Name or service not known"
160
+
161
+ retries += 1
162
+ return if retries >= max_retries
163
+
157
164
  puts " |_ ERROR: #{e.inspect} -- retrying"
158
165
  delay(5)
159
- retry
166
+ retry
160
167
 
161
168
  =begin
162
169
  rescue Mechanize::ResponseCodeError => e
@@ -0,0 +1,207 @@
1
+ require 'epitools'
2
+
3
+ ## Alias "Enumerator" to "Enum"
4
+
5
+ if RUBY_VERSION["1.8"]
6
+ require 'enumerator'
7
+ Enumerator = Enumerable::Enumerator unless defined? Enumerator
8
+ end
9
+
10
+ unless defined? Enum
11
+ if defined? Enumerator
12
+ Enum = Enumerator
13
+ else
14
+ $stderr.puts "WARNING: Couldn't find the Enumerator class. Enum will not be available."
15
+ end
16
+ end
17
+
18
+ RbConfig = Config unless defined? RbConfig
19
+
20
+
21
+ class Object
22
+ #
23
+ # Slightly gross hack to add a class method.
24
+ #
25
+ def self.alias_class_method(dest, src)
26
+ metaclass.send(:alias_method, dest, src)
27
+ end
28
+
29
+ end
30
+
31
+ require 'epitools/core_ext/object'
32
+ require 'epitools/core_ext/string'
33
+ require 'epitools/core_ext/array'
34
+ require 'epitools/core_ext/enumerable'
35
+ require 'epitools/core_ext/hash'
36
+ require 'epitools/core_ext/numbers'
37
+ require 'epitools/core_ext/truthiness'
38
+
39
+
40
+ class MatchData
41
+
42
+ #
43
+ # Return a hash of named matches
44
+ #
45
+ def to_hash
46
+ Hash[ names.zip(captures) ]
47
+ end
48
+
49
+ end
50
+
51
+
52
+ class Binding
53
+
54
+ def [](key)
55
+ eval(key.to_s)
56
+ end
57
+
58
+ def []=(key, val)
59
+ Thread.current[:_alter_binding_local_] = val
60
+ eval("#{key} = Thread.current[:_alter_binding_local_]")
61
+ Thread.current[:_alter_binding_local_] = nil
62
+ end
63
+
64
+ def local_variables
65
+ eval("local_variables")
66
+ end
67
+ alias_method :keys, :local_variables
68
+
69
+ end
70
+
71
+
72
+ class Proc
73
+
74
+ #
75
+ # Joins two procs together, returning a new proc.
76
+ #
77
+ # Example:
78
+ # newproc = proc { 1 } & proc { 2 }
79
+ # newproc.call #=> [1, 2]
80
+ #
81
+ def join(other=nil, &block)
82
+ other ||= block
83
+ proc { |*args| [self.call(*args), other.call(*args)] }
84
+ end
85
+ alias_method :&, :join
86
+
87
+ #
88
+ # Chains two procs together, returning a new proc. The output from each proc is passed into
89
+ # the input of the next one.
90
+ #
91
+ # Example:
92
+ # chain = proc { 1 } | proc { |input| input + 1 }
93
+ # chain.call #=> 2
94
+ #
95
+ def chain(other=nil, &block)
96
+ other ||= block
97
+ proc { |*args| other.call( self.call(*args) ) }
98
+ end
99
+ alias_method :|, :chain
100
+
101
+ end
102
+
103
+
104
+ unless defined?(BasicObject)
105
+ #
106
+ # A BasicObject class for Ruby 1.8
107
+ #
108
+ class BasicObject
109
+ instance_methods.each { |m| undef_method m unless m =~ /^__/ }
110
+ end
111
+ end
112
+
113
+
114
+
115
+ class NotWrapper < BasicObject # :nodoc:
116
+ def initialize(orig)
117
+ @orig = orig
118
+ end
119
+
120
+ def inspect
121
+ "{NOT #{@orig.inspect}}"
122
+ end
123
+
124
+ def method_missing(meth, *args, &block)
125
+ result = @orig.send(meth, *args, &block)
126
+ if result.is_a? ::TrueClass or result.is_a? ::FalseClass
127
+ !result
128
+ else
129
+ raise "Sorry, I don't know how to invert #{result.inspect}"
130
+ end
131
+ end
132
+ end
133
+
134
+ class Object
135
+
136
+ #
137
+ # Negates a boolean, chained-method style.
138
+ #
139
+ # Example:
140
+ # >> 10.even?
141
+ # => true
142
+ # >> 10.not.even?
143
+ # => false
144
+ #
145
+ def not
146
+ NotWrapper.new(self)
147
+ end
148
+
149
+ end
150
+
151
+ unless IO.respond_to? :copy_stream
152
+
153
+ class IO
154
+
155
+ def self.copy_stream(input, output)
156
+ while chunk = input.read(8192)
157
+ output.write(chunk)
158
+ end
159
+ end
160
+
161
+ end
162
+
163
+ end
164
+
165
+
166
+ class Range
167
+
168
+ #
169
+ # Pick a random number from the range.
170
+ #
171
+ def rand
172
+ magnitude = last-first
173
+ magnitude += 1 if not exclude_end?
174
+ Kernel.rand(magnitude)+first
175
+ end
176
+
177
+ end
178
+
179
+
180
+ class Struct
181
+
182
+ #
183
+ # Transform this struct into a JSON hash
184
+ #
185
+ def to_hash
186
+ hash = {}
187
+ each_pair { |k,v| hash[k] = v }
188
+ hash
189
+ end
190
+
191
+ #
192
+ # Transform the struct into a simple JSON hash.
193
+ #
194
+ def to_json(*args)
195
+ to_hash.to_json
196
+ end
197
+
198
+ end
199
+
200
+
201
+ module URI
202
+
203
+ def params
204
+ query.to_params
205
+ end
206
+
207
+ end
@@ -0,0 +1,98 @@
1
+
2
+ class Array
3
+
4
+ #
5
+ # flatten.compact.uniq
6
+ #
7
+ def squash
8
+ flatten.compact.uniq
9
+ end
10
+
11
+ #
12
+ # Removes the elements from the array for which the block evaluates to true.
13
+ # In addition, return the removed elements.
14
+ #
15
+ # For example, if you wanted to split an array into evens and odds:
16
+ #
17
+ # nums = [1,2,3,4,5,6,7,8,9,10,11,12]
18
+ # even = nums.remove_if { |n| n.even? } # remove all even numbers from the "nums" array and return them
19
+ # odd = nums # "nums" now only contains odd numbers
20
+ #
21
+ def remove_if(&block)
22
+ removed = []
23
+
24
+ delete_if do |x|
25
+ if block.call(x)
26
+ removed << x
27
+ true
28
+ else
29
+ false
30
+ end
31
+ end
32
+
33
+ removed
34
+ end
35
+
36
+ #
37
+ # zip from the right (or reversed zip.)
38
+ #
39
+ # eg:
40
+ # >> [5,39].rzip([:hours, :mins, :secs])
41
+ # => [ [:mins, 5], [:secs, 39] ]
42
+ #
43
+ def rzip(other)
44
+ # That's a lotta reverses!
45
+ reverse.zip(other.reverse).reverse
46
+ end
47
+
48
+ #
49
+ # Pick the middle element.
50
+ #
51
+ def middle
52
+ self[(size-1) / 2]
53
+ end
54
+
55
+ #
56
+ # XOR operator
57
+ #
58
+ def ^(other)
59
+ (self | other) - (self & other)
60
+ end
61
+
62
+ #
63
+ # Shuffle the array
64
+ #
65
+ unless defined? shuffle
66
+ def shuffle
67
+ sort_by{rand}
68
+ end
69
+ end
70
+
71
+ #
72
+ # Pick (a) random element(s).
73
+ #
74
+ unless defined? sample
75
+ def sample(n=1)
76
+ if n == 1
77
+ self[rand(size)]
78
+ else
79
+ shuffle[0...n]
80
+ end
81
+ end
82
+ end
83
+ alias_method :pick, :sample
84
+
85
+ #
86
+ # Divide the array into n pieces.
87
+ #
88
+ def / pieces
89
+ piece_size = (size.to_f / pieces).ceil
90
+ each_slice(piece_size).to_a
91
+ end
92
+
93
+
94
+ alias_method :unzip, :transpose
95
+
96
+ end
97
+
98
+