epitools 0.4.31 → 0.4.32

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/VERSION CHANGED
@@ -1 +1 @@
1
- 0.4.31
1
+ 0.4.32
@@ -5,11 +5,11 @@
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = %q{epitools}
8
- s.version = "0.4.31"
8
+ s.version = "0.4.32"
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-05-12}
12
+ s.date = %q{2011-05-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 = [
@@ -33,7 +33,6 @@ Gem::Specification.new do |s|
33
33
  "lib/epitools/hexdump.rb",
34
34
  "lib/epitools/its.rb",
35
35
  "lib/epitools/lcs.rb",
36
- "lib/epitools/metaclass.rb",
37
36
  "lib/epitools/niceprint.rb",
38
37
  "lib/epitools/numwords.rb",
39
38
  "lib/epitools/path.rb",
@@ -50,7 +49,6 @@ Gem::Specification.new do |s|
50
49
  "spec/browser_spec.rb",
51
50
  "spec/clitools_spec.rb",
52
51
  "spec/lcs_spec.rb",
53
- "spec/metaclass_spec.rb",
54
52
  "spec/numwords_spec.rb",
55
53
  "spec/path_spec.rb",
56
54
  "spec/permutations_spec.rb",
@@ -64,7 +62,7 @@ Gem::Specification.new do |s|
64
62
  s.homepage = %q{http://github.com/epitron/epitools}
65
63
  s.licenses = ["WTFPL"]
66
64
  s.require_paths = ["lib"]
67
- s.rubygems_version = %q{1.6.2}
65
+ s.rubygems_version = %q{1.7.2}
68
66
  s.summary = %q{NOT UTILS... METILS!}
69
67
 
70
68
  if s.respond_to? :specification_version then
@@ -24,7 +24,6 @@ require_wrapper = proc do |mod|
24
24
  end
25
25
 
26
26
  %w[
27
- metaclass
28
27
  basetypes
29
28
  niceprint
30
29
  string_to_proc
@@ -1,5 +1,4 @@
1
1
  require 'pp'
2
- require 'uri'
3
2
 
4
3
  # Alias "Enumerator" to "Enum"
5
4
 
@@ -17,6 +16,13 @@ unless defined? Enum
17
16
  end
18
17
 
19
18
  class Object
19
+ #
20
+ # Slightly gross hack to add a class method.
21
+ #
22
+ def self.alias_class_method(dest, src)
23
+ metaclass.send(:alias_method, dest, src)
24
+ end
25
+
20
26
  #
21
27
  # Default "integer?" behaviour.
22
28
  #
@@ -26,6 +32,7 @@ class Object
26
32
  # `truthy?` means `not blank?`
27
33
  #
28
34
  def truthy?; not blank?; end
35
+
29
36
  end
30
37
 
31
38
  class TrueClass
@@ -122,6 +129,7 @@ class String
122
129
  # Convert non-URI characters into %XXes.
123
130
  #
124
131
  def urlencode
132
+ require 'uri' unless defined? URI
125
133
  URI.escape(self)
126
134
  end
127
135
 
@@ -129,8 +137,63 @@ class String
129
137
  # Convert an URI's %XXes into regular characters.
130
138
  #
131
139
  def urldecode
140
+ require 'uri' unless defined? URI
132
141
  URI.unescape(self)
133
142
  end
143
+
144
+ #
145
+ # Convert a query string to a hash of params
146
+ #
147
+ def to_params
148
+ require 'cgi' unless defined? CGI
149
+ CGI.parse(self).map_values{|v| v.is_a?(Array) and v.size == 1 ? v.first : v }
150
+ end
151
+
152
+ #
153
+ # Decode a mime64/base64 encoded string
154
+ #
155
+ def decode64
156
+ require 'base64' unless defined? Base64
157
+ Base64.decode64 self
158
+ end
159
+
160
+ #
161
+ # Encode into a mime64/base64 string
162
+ #
163
+ def encode64
164
+ require 'base64' unless defined? Base64
165
+ Base64.encode64 self
166
+ end
167
+ alias_method :base64, :encode64
168
+
169
+ #
170
+ # MD5 the string
171
+ #
172
+ def md5
173
+ require 'digest/md5' unless defined? Digest::MD5
174
+ Digest::MD5.hexdigest self
175
+ end
176
+
177
+ #
178
+ # SHA1 the string
179
+ #
180
+ def sha1
181
+ require 'digest/sha1' unless defined? Digest::SHA1
182
+ Digest::SHA1.hexdigest self
183
+ end
184
+
185
+ # `true` if this string starts with the substring
186
+ #
187
+ def startswith(substring)
188
+ self[0...substring.size] == substring
189
+ end
190
+
191
+ #
192
+ # `true` if this string ends with the substring
193
+ #
194
+ def endswith(substring)
195
+ self[-substring.size..-1] == substring
196
+ end
134
197
 
135
198
  end
136
199
 
@@ -682,7 +745,7 @@ class Hash
682
745
  params.chop! # trailing &
683
746
  params
684
747
  end
685
-
748
+
686
749
  end
687
750
 
688
751
  unless defined?(BasicObject)
@@ -732,4 +795,28 @@ class Object
732
795
 
733
796
  end
734
797
 
798
+ # Metaclass
799
+ class Object
800
+ # The hidden singleton lurks behind everyone
801
+ def metaclass
802
+ class << self
803
+ self
804
+ end
805
+ end
806
+
807
+ def meta_eval &blk
808
+ metaclass.instance_eval &blk
809
+ end
810
+
811
+ # Adds methods to a metaclass
812
+ def meta_def name, &blk
813
+ meta_eval { define_method name, &blk }
814
+ end
815
+
816
+ # Defines an instance method within a class
817
+ def class_def name, &blk
818
+ class_eval { define_method name, &blk }
819
+ end
820
+ end
821
+
735
822
 
@@ -3,6 +3,7 @@ require 'mechanize'
3
3
  require 'uri'
4
4
  require 'fileutils'
5
5
 
6
+ require 'epitools'
6
7
  require 'epitools/browser/cache'
7
8
  require 'epitools/browser/mechanize_progressbar'
8
9
 
@@ -1,7 +1,9 @@
1
1
  require 'epitools/basetypes'
2
+ require 'fileutils'
3
+ require 'uri'
2
4
 
3
5
  class Path
4
-
6
+
5
7
  ## initializers
6
8
 
7
9
  def initialize(newpath)
@@ -13,14 +15,26 @@ class Path
13
15
  end
14
16
 
15
17
  def self.[](str)
16
- if str =~ /[\?\*]/ and not str =~ /\\[\?\*]/ # contains glob chars? (unescaped)
18
+ if str =~ %r{^[a-z\-]+://}i # URL?
19
+ Path::URL.new(str)
20
+ elsif str =~ /[\?\*]/ and not str =~ /\\[\?\*]/ # contains glob chars? (unescaped)
17
21
  glob(str)
18
22
  else
19
23
  new(str)
20
24
  end
21
25
  end
22
26
 
27
+ def self.tmpfile(prefix="tmp")
28
+ require 'tempfile' unless defined? Tempfile
29
+ file = Tempfile.new(prefix)
30
+ path = Path[file]
31
+ yield path if block_given?
32
+ path
33
+ end
23
34
 
35
+ alias_class_method :tempfile, :tmpfile
36
+
37
+
24
38
  ## setters
25
39
 
26
40
  attr_writer :base
@@ -34,7 +48,7 @@ class Path
34
48
  self.dir, self.filename = File.split(newpath)
35
49
  end
36
50
  else
37
- if newpath[-1..-1] == File::SEPARATOR # ends in '/'
51
+ if newpath.endswith(File::SEPARATOR) # ends in '/'
38
52
  self.dir = newpath
39
53
  else
40
54
  self.dir, self.filename = File.split(newpath)
@@ -67,7 +81,7 @@ class Path
67
81
  def ext=(newext)
68
82
  if newext.blank?
69
83
  @ext = nil
70
- elsif newext[0] == ?.
84
+ elsif newext.startswith('.')
71
85
  @ext = newext[1..-1]
72
86
  else
73
87
  @ext = newext
@@ -142,7 +156,15 @@ class Path
142
156
  def symlink?
143
157
  File.symlink? path
144
158
  end
145
-
159
+
160
+ def uri?
161
+ false
162
+ end
163
+
164
+ def url?
165
+ uri?
166
+ end
167
+
146
168
 
147
169
  ## aliases
148
170
 
@@ -164,7 +186,6 @@ class Path
164
186
 
165
187
  alias_method :directory?, :dir?
166
188
 
167
-
168
189
  ## comparisons
169
190
 
170
191
  include Comparable
@@ -202,8 +223,117 @@ class Path
202
223
  Path[File.join(path, "*")]
203
224
  end
204
225
 
226
+ ## modifying files
227
+
228
+ #
229
+ # Append
230
+ #
231
+ def append(data=nil)
232
+ self.open("ab") do |f|
233
+ if data and not block_given?
234
+ f.write(data)
235
+ else
236
+ yield f
237
+ end
238
+ end
239
+ end
240
+ alias_method :<<, :append
241
+
242
+ #
243
+ # Write a string, truncating the file
244
+ #
245
+ def write(data=nil)
246
+ self.open("wb") do |f|
247
+ if data and not block_given?
248
+ f.write(data)
249
+ else
250
+ yield f
251
+ end
252
+ end
253
+ end
254
+
255
+ #
256
+ # Rename
257
+ #
258
+ def rename(options)
259
+ raise "Options must be a Hash" unless options.is_a? Hash
260
+ dest = self.with(options)
261
+
262
+ raise "Error: destination (#{dest.inspect}) already exists" if dest.exists?
263
+ File.rename(path, dest)
264
+
265
+ self.path = dest.path # become dest
266
+ end
267
+
268
+ def rename_to(dest)
269
+ rename :path=>dest
270
+ end
271
+
272
+ alias_method :move, :rename
273
+ alias_method :ren, :rename
274
+
275
+ def delete!
276
+ File.unlink(self)
277
+ end
278
+ alias_method :"unlink!", :"delete!"
279
+
280
+ def mkdir_p
281
+ if exists?
282
+ raise "Error: Path already exists."
283
+ else
284
+ FileUtils.mkdir_p(path)
285
+ end
286
+ end
287
+
288
+ def cp_r(dest)
289
+ FileUtils.cp_r(path, dest) #if Path[dest].exists?
290
+ end
291
+
292
+ def join(other)
293
+ if uri?
294
+ Path[URI.join(path, other).to_s]
295
+ else
296
+ Path[File.join(path, other)]
297
+ end
298
+ end
299
+
300
+ end
301
+
302
+ #
303
+ # A wrapper for URL objects
304
+ #
305
+ class Path::URL < Path
306
+
307
+ attr_reader :uri
308
+
309
+ def initialize(uri)
310
+ @uri = URI.parse(uri)
311
+ self.path = @uri.path
312
+ end
313
+
314
+ def uri?
315
+ true
316
+ end
317
+
318
+ def host
319
+ uri.host
320
+ end
321
+
322
+ def query
323
+ if query = uri.query
324
+ query.to_params
325
+ else
326
+ nil
327
+ end
328
+ end
329
+
330
+ def to_s
331
+ uri.to_s
332
+ end
333
+
205
334
  end
206
335
 
336
+
207
337
  #
208
338
  # Path("/some/path") is an alias for Path["/some/path"]
209
339
  #
@@ -211,3 +341,10 @@ def Path(*args)
211
341
  Path[*args]
212
342
  end
213
343
 
344
+ if $0 == __FILE__
345
+ require 'ruby-debug'
346
+ #Path.pry
347
+ #Path["http://google.com/"].pry
348
+ debugger
349
+ Path["?"]
350
+ end
@@ -2,8 +2,6 @@
2
2
  # Cross-platform operating system functions.
3
3
  # Includes: process listing, platform detection, etc.
4
4
  #
5
- require 'epitools/metaclass'
6
-
7
5
  module Sys
8
6
 
9
7
  #-----------------------------------------------------------------------------
@@ -71,6 +71,21 @@ describe Object do
71
71
  10.not.even?.should == false
72
72
  end
73
73
 
74
+ it "alias_class_methods" do
75
+ class Blah
76
+ def self.classmethod
77
+ true
78
+ end
79
+
80
+ alias_class_method :aliased, :classmethod
81
+ end
82
+
83
+ lambda do
84
+ Blah.classmethod.should == true
85
+ end.should_not raise_error
86
+
87
+ end
88
+
74
89
  end
75
90
 
76
91
 
@@ -138,6 +153,22 @@ describe String do
138
153
  s.urlencode.should == "hi%20+%20there%20&%20mom%20+%20!!!!!%20I%20AM%20ON%20RSPEC"
139
154
  s.urlencode.urldecode.should == s
140
155
  end
156
+
157
+ it "to_paramses" do
158
+ "file=yay&setting=1&awesome=true".to_params.should == {"file" => "yay", "setting"=>"1", "awesome"=>"true"}
159
+ end
160
+
161
+ it "md5/sha1s" do
162
+ s = "hashme"
163
+ s.md5.should_not == s
164
+ s.sha1.should_not == s
165
+ s.sha1.should_not == s.md5
166
+ end
167
+
168
+ it "starts/endswith" do
169
+ "blahblahblah".startswith("blah").should == true
170
+ "blahblahblah".endswith("blah").should == true
171
+ end
141
172
 
142
173
  end
143
174
 
@@ -173,7 +204,6 @@ describe Integer do
173
204
  i[0..2].should == [1,1,0]
174
205
  i[-3..-1].should == [1,1,1]
175
206
  i[0..-1].should == [1,1,0,1,1,1]
176
-
177
207
  end
178
208
 
179
209
  end
@@ -320,7 +350,6 @@ describe "truthiness" do
320
350
 
321
351
  it "is truthy!" do
322
352
  {
323
-
324
353
  # truthy things
325
354
  true => [
326
355
  "asdf", 1, 1.7, :blah, true, [1,2,3], Enumerator.new([1,2,3], :each),
@@ -331,11 +360,21 @@ describe "truthiness" do
331
360
  false => [
332
361
  "", " ", 0, 0.0, false, nil, [], Enumerator.new([], :each),
333
362
  ]
334
-
335
363
  }.each do |truthiness, objs|
336
364
  objs.each { |obj| obj.truthy?.should == truthiness }
337
365
  end
338
-
339
366
  end
340
367
 
341
368
  end
369
+
370
+
371
+ describe "metaclass" do
372
+
373
+ it "metaclass" do
374
+ o = Object.new
375
+ o_metaclass = class << o; self; end
376
+ o.metaclass.should == o_metaclass
377
+ end
378
+
379
+ end
380
+
@@ -125,4 +125,50 @@ describe Path do
125
125
  path.path.should == '/spam/spam/spam/humbug/'
126
126
  end
127
127
 
128
+ it "handles URLs" do
129
+ path = Path["http://google.com/?search=blah"]
130
+ path.host.should == "google.com"
131
+ path.query.should == {"search" => "blah"}
132
+ path.uri?.should == true
133
+ end
134
+
135
+ it "tempfiles" do
136
+ path = Path.tmpfile
137
+ path.exists?.should == true
138
+ end
139
+
140
+ it "appends and writes" do
141
+ path = Path.tmpfile
142
+ path.exists?.should == true
143
+
144
+ path.write "blah"
145
+ path.append "what"
146
+ path << "lul"
147
+
148
+ path.read.should == "blahwhatlul"
149
+
150
+ path.write "rawr"
151
+
152
+ path.read.should == "rawr"
153
+ end
154
+
155
+ it "renames" do
156
+ path = Path.tmpfile
157
+
158
+ str = path.to_s
159
+
160
+ path.rename(:ext=>".dat")
161
+
162
+ path.to_s.should_not == str
163
+ path.to_s.should == str+".dat"
164
+ end
165
+
166
+ it "deletes" do
167
+ path = Path.tmpfile
168
+ path << "data"
169
+ path.exists?.should == true
170
+ path.delete!
171
+ path.exists?.should == false
172
+ end
173
+
128
174
  end
@@ -56,9 +56,12 @@ describe Sys::ProcessInfo do
56
56
 
57
57
 
58
58
  specify "cross-platform method" do
59
- Sys.interfaces.should_not be_nil
60
59
  Sys.cross_platform_method(:cross_platform_test)
61
60
  proc{ Sys.cross_platform_test }.should raise_error
62
61
  end
63
62
 
63
+ specify "interfaces" do
64
+ Sys.interfaces.should_not be_nil
65
+ end
66
+
64
67
  end
metadata CHANGED
@@ -1,8 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: epitools
3
3
  version: !ruby/object:Gem::Version
4
+ hash: 79
4
5
  prerelease:
5
- version: 0.4.31
6
+ segments:
7
+ - 0
8
+ - 4
9
+ - 32
10
+ version: 0.4.32
6
11
  platform: ruby
7
12
  authors:
8
13
  - epitron
@@ -10,8 +15,7 @@ autorequire:
10
15
  bindir: bin
11
16
  cert_chain: []
12
17
 
13
- date: 2011-05-12 00:00:00 -04:00
14
- default_executable:
18
+ date: 2011-05-15 00:00:00 Z
15
19
  dependencies:
16
20
  - !ruby/object:Gem::Dependency
17
21
  name: rspec
@@ -21,6 +25,11 @@ dependencies:
21
25
  requirements:
22
26
  - - ~>
23
27
  - !ruby/object:Gem::Version
28
+ hash: 7
29
+ segments:
30
+ - 2
31
+ - 2
32
+ - 0
24
33
  version: 2.2.0
25
34
  type: :development
26
35
  version_requirements: *id001
@@ -32,6 +41,11 @@ dependencies:
32
41
  requirements:
33
42
  - - ~>
34
43
  - !ruby/object:Gem::Version
44
+ hash: 23
45
+ segments:
46
+ - 1
47
+ - 0
48
+ - 0
35
49
  version: 1.0.0
36
50
  type: :development
37
51
  version_requirements: *id002
@@ -43,6 +57,9 @@ dependencies:
43
57
  requirements:
44
58
  - - ">="
45
59
  - !ruby/object:Gem::Version
60
+ hash: 3
61
+ segments:
62
+ - 0
46
63
  version: "0"
47
64
  type: :development
48
65
  version_requirements: *id003
@@ -72,7 +89,6 @@ files:
72
89
  - lib/epitools/hexdump.rb
73
90
  - lib/epitools/its.rb
74
91
  - lib/epitools/lcs.rb
75
- - lib/epitools/metaclass.rb
76
92
  - lib/epitools/niceprint.rb
77
93
  - lib/epitools/numwords.rb
78
94
  - lib/epitools/path.rb
@@ -89,7 +105,6 @@ files:
89
105
  - spec/browser_spec.rb
90
106
  - spec/clitools_spec.rb
91
107
  - spec/lcs_spec.rb
92
- - spec/metaclass_spec.rb
93
108
  - spec/numwords_spec.rb
94
109
  - spec/path_spec.rb
95
110
  - spec/permutations_spec.rb
@@ -99,7 +114,6 @@ files:
99
114
  - spec/spec_helper.rb
100
115
  - spec/sys_spec.rb
101
116
  - spec/zopen_spec.rb
102
- has_rdoc: true
103
117
  homepage: http://github.com/epitron/epitools
104
118
  licenses:
105
119
  - WTFPL
@@ -113,17 +127,23 @@ required_ruby_version: !ruby/object:Gem::Requirement
113
127
  requirements:
114
128
  - - ">="
115
129
  - !ruby/object:Gem::Version
130
+ hash: 3
131
+ segments:
132
+ - 0
116
133
  version: "0"
117
134
  required_rubygems_version: !ruby/object:Gem::Requirement
118
135
  none: false
119
136
  requirements:
120
137
  - - ">="
121
138
  - !ruby/object:Gem::Version
139
+ hash: 3
140
+ segments:
141
+ - 0
122
142
  version: "0"
123
143
  requirements: []
124
144
 
125
145
  rubyforge_project:
126
- rubygems_version: 1.6.2
146
+ rubygems_version: 1.7.2
127
147
  signing_key:
128
148
  specification_version: 3
129
149
  summary: NOT UTILS... METILS!
@@ -1,28 +0,0 @@
1
- class Object
2
- # The hidden singleton lurks behind everyone
3
- def metaclass
4
- class << self
5
- self
6
- end
7
- end
8
-
9
- def meta_eval &blk
10
- metaclass.instance_eval &blk
11
- end
12
-
13
- # Adds methods to a metaclass
14
- def meta_def name, &blk
15
- meta_eval { define_method name, &blk }
16
- end
17
-
18
- # Defines an instance method within a class
19
- def class_def name, &blk
20
- class_eval { define_method name, &blk }
21
- end
22
- end
23
-
24
- if $0 == __FILE__
25
- o = Object.new
26
- p o
27
- p o.metaclass
28
- end
@@ -1,12 +0,0 @@
1
- require 'epitools/metaclass'
2
-
3
- describe "Metaclass" do
4
-
5
- it "metaclass" do
6
- o = Object.new
7
- o_metaclass = class << o; self; end
8
- o.metaclass.should == o_metaclass
9
- end
10
-
11
- end
12
-