richfile 0.0.4

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,51 @@
1
+ = Richfile
2
+
3
+ A simple gem which adds some additional methods to File objects.
4
+
5
+ == Install
6
+
7
+ gem install tsalzer-richfile --source http://gems.github.com
8
+
9
+
10
+ == What is Richfile?
11
+
12
+ Richfile extends the Ruby built-in File instances with some sometimes
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)
16
+
17
+ Note that there is no built-in magic to keep the once-fetched attributes
18
+ in sync with the effective attributes of the real files.
19
+
20
+ == Usage
21
+
22
+ You simple require richfile:
23
+
24
+ require 'richfile'
25
+
26
+ Now, every new File object has a list of additional attributes. Whenever you
27
+ access the attributes the first time, the data is pulled from the file system
28
+ and cached in the File object.
29
+
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
32
+ attributes. When you are just interested in a single attribute, call the
33
+ attribute with an added bang (like <code>size!</code>).
34
+
35
+ == Building a new Gem
36
+
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
40
+
41
+ rake gemspec
42
+ gem build richfile.gemspec
43
+
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
47
+
48
+ == License
49
+
50
+ The richfile gem comes to you under the MIT License. You should find the
51
+ license text in the file MIT-LICENSE in the gem folder.
@@ -0,0 +1,4 @@
1
+ ---
2
+ :minor: 0
3
+ :patch: 4
4
+ :major: 0
@@ -0,0 +1,4 @@
1
+ require "richfile/base"
2
+ require "richfile/digests"
3
+ require "richfile/mimetype"
4
+ Richfile.install
@@ -0,0 +1,55 @@
1
+ # Extension to File.
2
+ module Richfile
3
+
4
+ # Methods to be included in File objects.
5
+ module Base
6
+ # size of the file in bytes.
7
+ attr_reader :size
8
+
9
+ # refresh the Richfile added attributes.
10
+ # All the attributes referred once are loaded.
11
+ def refresh!
12
+ self.size! if @size
13
+ refresh_digests! if respond_to?(:refresh_all_digests!)
14
+ self.mimetype! if @mimetype
15
+ self
16
+ end
17
+
18
+ # refresh all attributes.
19
+ # All attributes wil be loaded, so all digests will be calculated.
20
+ # You will most probably never need this method.
21
+ def refresh_all!
22
+ self.size!
23
+ refresh_all_digests! if respond_to?(:refresh_all_digests!)
24
+ self.mimetype!
25
+ self
26
+ end
27
+
28
+ # proxies File.exists?.
29
+ # This will always go to the real File.exists?, it will not be cached.
30
+ def exists?
31
+ File.exists?(path)
32
+ end
33
+
34
+ # size of the file in bytes.
35
+ # see File#size
36
+ def size
37
+ @size = File.size(self.path) unless @size
38
+ @size
39
+ end
40
+ # refresh the size attribute.
41
+ def size!
42
+ @size = nil
43
+ self.size
44
+ end
45
+
46
+ end#Base
47
+
48
+ # include the Richfile::Base module into the File class.
49
+ def self.install
50
+ File.send :include, Richfile::Base
51
+ File.send :include, Richfile::Digests::Base
52
+ File.send :include, Richfile::Mimetype::Base
53
+ end
54
+
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 ADDED
@@ -0,0 +1,61 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: richfile
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.4
5
+ platform: ruby
6
+ authors:
7
+ - Till Salzer
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+
12
+ date: 2009-04-02 00:00:00 +02:00
13
+ default_executable:
14
+ dependencies: []
15
+
16
+ description: Extends Ruby File objects with some rich instance attributes.
17
+ email: till.salzer@googlemail.com
18
+ executables: []
19
+
20
+ extensions: []
21
+
22
+ extra_rdoc_files:
23
+ - README.rdoc
24
+ files:
25
+ - README.rdoc
26
+ - VERSION.yml
27
+ - lib/richfile/base.rb
28
+ - lib/richfile/digests.rb
29
+ - lib/richfile/mimetype.rb
30
+ - lib/richfile.rb
31
+ has_rdoc: true
32
+ homepage: http://github.com/tsalzer/richfile
33
+ licenses: []
34
+
35
+ post_install_message:
36
+ rdoc_options:
37
+ - --inline-source
38
+ - --charset=UTF-8
39
+ require_paths:
40
+ - lib
41
+ required_ruby_version: !ruby/object:Gem::Requirement
42
+ requirements:
43
+ - - ">="
44
+ - !ruby/object:Gem::Version
45
+ version: "0"
46
+ version:
47
+ required_rubygems_version: !ruby/object:Gem::Requirement
48
+ requirements:
49
+ - - ">="
50
+ - !ruby/object:Gem::Version
51
+ version: "0"
52
+ version:
53
+ requirements: []
54
+
55
+ rubyforge_project:
56
+ rubygems_version: 1.3.4
57
+ signing_key:
58
+ specification_version: 2
59
+ summary: More attributes for Ruby File
60
+ test_files: []
61
+