epitools 0.5.1 → 0.5.2

Sign up to get free protection for your applications and to get access to all the features.
@@ -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
+