tsalzer-richfile 0.0.3 → 0.0.4

Sign up to get free protection for your applications and to get access to all the features.
@@ -7,10 +7,12 @@ A simple gem which adds some additional methods to File objects.
7
7
  gem install tsalzer-richfile --source http://gems.github.com
8
8
 
9
9
 
10
- == What is a Richfile?
10
+ == What is Richfile?
11
11
 
12
- Richfile extends the Ruby built-in File instances with some somtimes
12
+ Richfile extends the Ruby built-in File instances with some sometimes
13
13
  useful attributes.
14
+ - +size+ attribute to cache the file size in a File object
15
+ - OpenSSL digest attributes like <code>md5</code> and <code>sha1</code> (for all available digests)
14
16
 
15
17
  Note that there is no built-in magic to keep the once-fetched attributes
16
18
  in sync with the effective attributes of the real files.
@@ -25,23 +27,23 @@ Now, every new File object has a list of additional attributes. Whenever you
25
27
  access the attributes the first time, the data is pulled from the file system
26
28
  and cached in the File object.
27
29
 
28
- If you need to refresh the data, either call +refresh!+, which updates every
29
- attribute you used before, or +refresh_all!+, which updates each of the cached
30
+ If you need to refresh the data, either call <code>refresh!</code>, which updates every
31
+ attribute you used before, or <code>refresh_all!</code>, which updates each of the cached
30
32
  attributes. When you are just interested in a single attribute, call the
31
- attribute with an added bang (like +size!+).
33
+ attribute with an added bang (like <code>size!</code>).
32
34
 
33
35
  == Building a new Gem
34
36
 
35
- To create a new gem, you need to install the echoe gem (see
36
- http://blog.evanweaver.com/files/doc/fauna/echoe/files/README.html).
37
- Next, edit the Rakefile to reflect your changes, then run:
37
+ To create a new gem, you need to install the jeweler gem (see
38
+ http://github.com/technicalpickles/jeweler/tree/master). If this is done, you can
39
+ easily build a new gemspec with
38
40
 
39
- rake clobber # remove generated stuff for a clean manifest
40
- rake manifest # only needed if you changed the file set
41
- rake build_gemspec # update the gemspec
41
+ rake gemspec
42
+ gem build richfile.gemspec
42
43
 
43
- Now, you can either publish the gem, or build a gem package. See rake -T for
44
- available targets.
44
+ This would create a new richfile-x.y.z.gem, which can easily be installed via
45
+
46
+ gem install richfile-x.y.z.gem
45
47
 
46
48
  == License
47
49
 
@@ -1,4 +1,4 @@
1
1
  ---
2
- :major: 0
3
2
  :minor: 0
4
- :patch: 3
3
+ :patch: 4
4
+ :major: 0
@@ -1,2 +1,4 @@
1
- require "#{File.dirname(__FILE__)}/richfile/base"
1
+ require "richfile/base"
2
+ require "richfile/digests"
3
+ require "richfile/mimetype"
2
4
  Richfile.install
@@ -1,55 +1,17 @@
1
- require 'openssl'
2
-
3
1
  # Extension to File.
4
2
  module Richfile
5
- if OpenSSL::OPENSSL_VERSION_NUMBER > 0x00908000
6
- DIGESTS = %w(DSS1 MD2 MD4 MD5 RIPEMD160 SHA SHA1 SHA224 SHA256 SHA384 SHA512)
7
- else
8
- DIGESTS = %w(DSS1 MD2 MD4 MD5 RIPEMD160 SHA SHA1)
9
- end
10
3
 
11
- def self.digest_variants(digest)
12
- digest_downcase = digest.downcase
13
- digest_symbol = digest_downcase.to_sym
14
- digest_bang = "#{digest_downcase}!".to_sym
15
- digest_variable = "@#{digest_downcase}".to_sym
16
- return digest_downcase, digest_symbol, digest_bang, digest_variable
17
- end
18
-
19
4
  # Methods to be included in File objects.
20
5
  module Base
21
6
  # size of the file in bytes.
22
7
  attr_reader :size
23
8
 
24
- # define attributes for all the digests in Richfile::DIGEST.
25
- Richfile::DIGESTS.each do |digest|
26
- d_downcase, d_sym, d_bang, d_var = Richfile.digest_variants(digest)
27
-
28
- # message digest #{digest}
29
- attr_reader d_sym
30
-
31
- define_method d_sym do
32
- instance_variable_set(d_var, File.open(path, 'r') do |f|
33
- d = OpenSSL::Digest.new(digest)
34
- d << f.read
35
- d.hexdigest
36
- end) unless instance_variable_get(d_var)
37
- instance_variable_get(d_var)
38
- end
39
- define_method d_bang do
40
- instance_variable_set(d_var, nil)
41
- send d_sym
42
- end
43
- end
44
-
45
9
  # refresh the Richfile added attributes.
46
10
  # All the attributes referred once are loaded.
47
11
  def refresh!
48
12
  self.size! if @size
49
- DIGESTS.each do |digest|
50
- d_downcase, d_sym, d_bang, d_var = Richfile.digest_variants(digest)
51
- send d_bang if (instance_variable_get(d_var))
52
- end
13
+ refresh_digests! if respond_to?(:refresh_all_digests!)
14
+ self.mimetype! if @mimetype
53
15
  self
54
16
  end
55
17
 
@@ -58,10 +20,8 @@ module Base
58
20
  # You will most probably never need this method.
59
21
  def refresh_all!
60
22
  self.size!
61
- DIGESTS.each do |digest|
62
- d_downcase, d_sym, d_bang, d_var = Richfile.digest_variants(digest)
63
- send d_bang
64
- end
23
+ refresh_all_digests! if respond_to?(:refresh_all_digests!)
24
+ self.mimetype!
65
25
  self
66
26
  end
67
27
 
@@ -88,6 +48,8 @@ end#Base
88
48
  # include the Richfile::Base module into the File class.
89
49
  def self.install
90
50
  File.send :include, Richfile::Base
51
+ File.send :include, Richfile::Digests::Base
52
+ File.send :include, Richfile::Mimetype::Base
91
53
  end
92
54
 
93
55
  end#Richfile
@@ -0,0 +1,280 @@
1
+ require 'openssl'
2
+
3
+ module Richfile
4
+
5
+ # Digest related functionality.
6
+ module Digests
7
+
8
+ if OpenSSL::OPENSSL_VERSION_NUMBER > 0x00908000
9
+ # all known digests for OpenSSL > 0.9.8
10
+ DIGESTS = %w(DSS1 MD2 MD4 MD5 RIPEMD160 SHA SHA1 SHA224 SHA256 SHA384 SHA512)
11
+ else
12
+ # all known digests for OpenSSL up to 0.9.8
13
+ DIGESTS = %w(DSS1 MD2 MD4 MD5 RIPEMD160 SHA SHA1)
14
+ end
15
+
16
+ def self.each_digest_symbols(&blk) #:nodoc:
17
+ DIGESTS.each do |digest|
18
+ digest_downcase = digest.downcase
19
+ digest_bang = "#{digest_downcase}!".to_sym
20
+ digest_variable = "@#{digest_downcase}".to_sym
21
+
22
+ blk.call(digest_bang, digest_variable)
23
+ end
24
+ end
25
+
26
+ # Digest-related methods and attributes to be included in File objects.
27
+ module InstanceMethods
28
+ # DSS1 message digest.
29
+ attr_reader :dss1
30
+ # caching getter for DSS1 message digest.
31
+ def dss1
32
+ @dss1 = self.class.dss1(path) unless @dss1
33
+ @dss1
34
+ end
35
+ # getter for DSS1 message digest.
36
+ # This getter forces the digest to be reloaded.
37
+ def dss1!
38
+ @dss1 = nil
39
+ dss1
40
+ end
41
+
42
+ # MD2 message digest.
43
+ attr_reader :md2
44
+ # caching getter for MD2 message digest.
45
+ def md2
46
+ @md2 = self.class.md2(path) unless @md2
47
+ @md2
48
+ end
49
+ # getter for MD2 message digest.
50
+ # This getter forces the digest to be reloaded.
51
+ def md2!
52
+ @md2 = nil
53
+ md2
54
+ end
55
+
56
+ # MD4 message digest.
57
+ attr_reader :md4
58
+ # caching getter for MD4 message digest.
59
+ def md4
60
+ @md4 = self.class.md4(path) unless @md4
61
+ @md4
62
+ end
63
+ # getter for MD4 message digest.
64
+ # This getter forces the digest to be reloaded.
65
+ def md4!
66
+ @md4 = nil
67
+ md4
68
+ end
69
+
70
+ # MD5 message digest.
71
+ attr_reader :md5
72
+ # caching getter for MD5 message digest.
73
+ def md5
74
+ @md5 = self.class.md5(path) unless @md5
75
+ @md5
76
+ end
77
+ # getter for MD5 message digest.
78
+ # This getter forces the digest to be reloaded.
79
+ def md5!
80
+ @md5 = nil
81
+ md5
82
+ end
83
+
84
+ # RIPEMD160 message digest.
85
+ attr_reader :ripemd160
86
+ # caching getter for RIPEMD160 message digest.
87
+ def ripemd160
88
+ @ripemd160 = self.class.ripemd160(path) unless @ripemd160
89
+ @ripemd160
90
+ end
91
+ # getter for RIPEMD160 message digest.
92
+ # This getter forces the digest to be reloaded.
93
+ def ripemd160!
94
+ @ripemd160 = nil
95
+ ripemd160
96
+ end
97
+
98
+ # SHA message digest.
99
+ attr_reader :sha
100
+ # caching getter for SHA message digest.
101
+ def sha
102
+ @sha = self.class.sha(path) unless @sha
103
+ @sha
104
+ end
105
+ # getter for SHA message digest.
106
+ # This getter forces the digest to be reloaded.
107
+ def sha!
108
+ @sha = nil
109
+ sha
110
+ end
111
+
112
+ # SHA1 message digest.
113
+ attr_reader :sha1
114
+ # caching getter for SHA1 message digest.
115
+ def sha1
116
+ @sha1 = self.class.sha1(path) unless @sha1
117
+ @sha1
118
+ end
119
+ # getter for SHA1 message digest.
120
+ # This getter forces the digest to be reloaded.
121
+ def sha1!
122
+ @sha1 = nil
123
+ sha1
124
+ end
125
+
126
+ # SHA224 message digest.
127
+ attr_reader :sha224
128
+ # caching getter for SHA224 message digest.
129
+ def sha224
130
+ @sha224 = self.class.sha224(path) unless @sha224
131
+ @sha224
132
+ end
133
+ # getter for SHA224 message digest.
134
+ # This getter forces the digest to be reloaded.
135
+ def sha224!
136
+ @sha224 = nil
137
+ sha224
138
+ end
139
+
140
+ # SHA256 message digest.
141
+ attr_reader :sha256
142
+ # caching getter for SHA256 message digest.
143
+ def sha256
144
+ @sha256 = self.class.sha256(path) unless @sha256
145
+ @sha256
146
+ end
147
+ # getter for SHA256 message digest.
148
+ # This getter forces the digest to be reloaded.
149
+ def sha256!
150
+ @sha256 = nil
151
+ sha256
152
+ end
153
+
154
+ # SHA384 message digest.
155
+ attr_reader :sha384
156
+ # caching getter for SHA384 message digest.
157
+ def sha384
158
+ @sha384 = self.class.sha384(path) unless @sha384
159
+ @sha384
160
+ end
161
+ # getter for SHA384 message digest.
162
+ # This getter forces the digest to be reloaded.
163
+ def sha384!
164
+ @sha384 = nil
165
+ sha384
166
+ end
167
+
168
+ # SHA512 message digest.
169
+ attr_reader :sha512
170
+ # caching getter for SHA512 message digest.
171
+ def sha512
172
+ @sha512 = self.class.sha512(path) unless @sha512
173
+ @sha512
174
+ end
175
+ # getter for SHA512 message digest.
176
+ # This getter forces the digest to be reloaded.
177
+ def sha512!
178
+ @sha512 = nil
179
+ sha512
180
+ end
181
+
182
+ # refresh the Richfile added attributes.
183
+ # All the attributes referred once are loaded.
184
+ def refresh_digests!
185
+ Richfile::Digests::each_digest_symbols do |d_bang, d_var|
186
+ send d_bang if (instance_variable_get(d_var))
187
+ end
188
+ self
189
+ end
190
+ # refresh all attributes.
191
+ # All attributes wil be loaded, so all digests will be calculated.
192
+ # You will most probably never need this method.
193
+ def refresh_all_digests!
194
+ Richfile::Digests::each_digest_symbols do |d_bang, d_var|
195
+ send d_bang
196
+ end
197
+ self
198
+ end
199
+ end#InstanceMethods
200
+
201
+ # Digest-related methods to be included into File class.
202
+ module ClassMethods
203
+ # compute the DSS1 digest of a file.
204
+ def dss1(path)
205
+ hexdigest('DSS1', path)
206
+ end
207
+ # compute the DSS1 digest of a file.
208
+ # uses digest with 'DSS1' as digest to be used.
209
+ def md2(path)
210
+ hexdigest('MD2', path)
211
+ end
212
+ # compute the MD4 digest of a file.
213
+ # uses digest with 'MD4' as digest to be used.
214
+ def md4(path)
215
+ hexdigest('MD4', path)
216
+ end
217
+ # compute the MD5 digest of a file.
218
+ # uses digest with 'MD5' as digest to be used.
219
+ def md5(path)
220
+ hexdigest('MD5', path)
221
+ end
222
+ # compute the RIPEMD160 digest of a file.
223
+ # uses digest with 'RIPEMD160' as digest to be used.
224
+ def ripemd160(path)
225
+ hexdigest('RIPEMD160', path)
226
+ end
227
+ # compute the SHA digest of a file.
228
+ # uses digest with 'SHA' as digest to be used.
229
+ def sha(path)
230
+ hexdigest('SHA', path)
231
+ end
232
+ # compute the SHA1 digest of a file.
233
+ # uses digest with 'SHA1' as digest to be used.
234
+ def sha1(path)
235
+ hexdigest('SHA1', path)
236
+ end
237
+ # compute the SHA224 digest of a file.
238
+ # uses digest with 'SHA224' as digest to be used.
239
+ def sha224(path)
240
+ hexdigest('SHA224', path)
241
+ end
242
+ # compute the SHA256 digest of a file.
243
+ # uses digest with 'SHA256' as digest to be used.
244
+ def sha256(path)
245
+ hexdigest('SHA256', path)
246
+ end
247
+ # compute the SHA384 digest of a file.
248
+ # uses digest with 'SHA384' as digest to be used.
249
+ def sha384(path)
250
+ hexdigest('SHA384', path)
251
+ end
252
+ # compute the SHA512 digest of a file.
253
+ # uses digest with 'SHA512' as digest to be used.
254
+ def sha512(path)
255
+ hexdigest('SHA512', path)
256
+ end
257
+
258
+ # compute a digest for a given file.
259
+ # - digest: the OpenSSL digest name
260
+ # - path: the file path
261
+ # - returns: hexdigest of the content of the file at the given path
262
+ def hexdigest(digest, path)
263
+ File.open(path, 'r') do |f|
264
+ d = OpenSSL::Digest.new(digest)
265
+ d << f.read
266
+ d.hexdigest
267
+ end
268
+ end
269
+ end#DigestClassmethods
270
+
271
+ module Base #:nodoc:
272
+ def self.included(mod) #:nodoc:
273
+ mod.extend(Richfile::Digests::ClassMethods)
274
+ mod.class_eval { include(Richfile::Digests::InstanceMethods) }
275
+ end
276
+ end#Base
277
+
278
+ end#Digests
279
+
280
+ end#Richfile
@@ -0,0 +1,54 @@
1
+ #require 'mime/types'
2
+
3
+ module Richfile
4
+
5
+ # Mimetype functionality for attributes for File objects.
6
+ # Currently, this works only for Unix-like OS, since it uses the file system
7
+ # utility.
8
+ module Mimetype
9
+
10
+ # Methods made available for instances.
11
+ module InstanceMethods
12
+ # the MIME type.
13
+ attr_reader :mimetype
14
+ # get the MIME type.
15
+ def mimetype
16
+ @mimetype = self.class.mimetype(path) unless @mimetype
17
+ @mimetype
18
+ end
19
+ # re-fetch the MIME type.
20
+ def mimetype!
21
+ @mimetype = nil
22
+ self.mimetype
23
+ end
24
+ end#InstanceMethods
25
+
26
+ # Methods implanted into the File class itself.
27
+ module ClassMethods
28
+ # get the MIME type from a file using Richfile::Mimetype.mimetype_using_file.
29
+ def mimetype(path)
30
+ Richfile::Mimetype.mimetype_using_file(path).first
31
+ end
32
+ end#ClassMethods
33
+
34
+ # determinate the MimeType using the file system utility.
35
+ # This is probably only available on Unix-like systems, but is usually
36
+ # quite reliable.
37
+ #
38
+ # - path: the full path of the file
39
+ # - returns: the mimetype string
40
+ def self.mimetype_using_file(path)
41
+ mimestring = `file --mime -b "#{path}"`.gsub(/\n/,"")
42
+ mimetype, encoding = /(\w+\/\w+); (.+)/.match(mimestring)[1,2]
43
+ return mimetype, encoding
44
+ end
45
+
46
+ module Base #:nodoc:
47
+ def self.included(mod) #:nodoc:
48
+ mod.extend(Richfile::Mimetype::ClassMethods)
49
+ mod.class_eval { include(Richfile::Mimetype::InstanceMethods) }
50
+ end
51
+ end#Base
52
+
53
+ end#Mimetype
54
+ end#Richfile
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: tsalzer-richfile
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.3
4
+ version: 0.0.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - Till Salzer
@@ -9,7 +9,7 @@ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
11
 
12
- date: 2009-03-26 00:00:00 -07:00
12
+ date: 2009-04-02 00:00:00 -07:00
13
13
  default_executable:
14
14
  dependencies: []
15
15
 
@@ -26,6 +26,8 @@ files:
26
26
  - VERSION.yml
27
27
  - lib/richfile
28
28
  - lib/richfile/base.rb
29
+ - lib/richfile/digests.rb
30
+ - lib/richfile/mimetype.rb
29
31
  - lib/richfile.rb
30
32
  has_rdoc: true
31
33
  homepage: http://github.com/tsalzer/richfile