tsalzer-richfile 0.0.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.
data/MIT-LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2009 Till Salzer
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.rdoc ADDED
@@ -0,0 +1,49 @@
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 a Richfile?
11
+
12
+ Richfile extends the Ruby built-in File instances with some somtimes
13
+ useful attributes.
14
+
15
+ Note that there is no built-in magic to keep the once-fetched attributes
16
+ in sync with the effective attributes of the real files.
17
+
18
+ == Usage
19
+
20
+ You simple require richfile:
21
+
22
+ require 'richfile'
23
+
24
+ Now, every new File object has a list of additional attributes. Whenever you
25
+ access the attributes the first time, the data is pulled from the file system
26
+ and cached in the File object.
27
+
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
+ attributes. When you are just interested in a single attribute, call the
31
+ attribute with an added bang (like +size!+).
32
+
33
+ == Building a new Gem
34
+
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:
38
+
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
42
+
43
+ Now, you can either publish the gem, or build a gem package. See rake -T for
44
+ available targets.
45
+
46
+ == License
47
+
48
+ The richfile gem comes to you under the MIT License. You should find the
49
+ license text in the file MIT-LICENSE in the gem folder.
data/Rakefile ADDED
@@ -0,0 +1,17 @@
1
+ # Rakefile for img_gravatar
2
+ require 'rubygems'
3
+ require 'rake'
4
+ task :default => [:specs]
5
+ require 'echoe'
6
+
7
+ Echoe.new('richfile', '0.0.2') do |p|
8
+ p.description = "Extends File objects with some rich instance attributes."
9
+ p.url = "http://github.com/tsalzer/richfile"
10
+ p.author = "Till Salzer"
11
+ p.email = "till.salzer@googlemail.com"
12
+ p.ignore_pattern = ["tmp/*", "script/*", "rdoc/*", "pkg/*", "coverage/*", "*.tmproj"]
13
+ p.development_dependencies = ['rspec','rcov']
14
+ p.rdoc_pattern = /^(lib|bin|tasks|ext)|^README.rdoc|^CHANGELOG|^TODO|^MIT-LICENSE|^COPYING$/
15
+ end
16
+
17
+ Dir["#{File.dirname(__FILE__)}/tasks/*.rake"].sort.each { |ext| load ext }
data/init.rb ADDED
@@ -0,0 +1,3 @@
1
+ # Include hook code here
2
+
3
+ require 'richfile'
data/install.rb ADDED
@@ -0,0 +1 @@
1
+ # Install hook code here
@@ -0,0 +1,93 @@
1
+ require 'openssl'
2
+
3
+ # Extension to File.
4
+ 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
+
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
+ # Methods to be included in File objects.
20
+ module Base
21
+ # size of the file in bytes.
22
+ attr_reader :size
23
+
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
+ # refresh the Richfile added attributes.
46
+ # All the attributes referred once are loaded.
47
+ def refresh!
48
+ 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
53
+ self
54
+ end
55
+
56
+ # refresh all attributes.
57
+ # All attributes wil be loaded, so all digests will be calculated.
58
+ # You will most probably never need this method.
59
+ def refresh_all!
60
+ 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
65
+ self
66
+ end
67
+
68
+ # proxies File.exists?.
69
+ # This will always go to the real File.exists?, it will not be cached.
70
+ def exists?
71
+ File.exists?(path)
72
+ end
73
+
74
+ # size of the file in bytes.
75
+ # see File#size
76
+ def size
77
+ @size = File.size(self.path) unless @size
78
+ @size
79
+ end
80
+ # refresh the size attribute.
81
+ def size!
82
+ @size = nil
83
+ self.size
84
+ end
85
+
86
+ end#Base
87
+
88
+ # include the Richfile::Base module into the File class.
89
+ def self.install
90
+ File.send :include, Richfile::Base
91
+ end
92
+
93
+ end#Richfile
data/lib/richfile.rb ADDED
@@ -0,0 +1,2 @@
1
+ require "#{File.dirname(__FILE__)}/richfile/base"
2
+ Richfile.install
data/richfile.gemspec ADDED
@@ -0,0 +1,37 @@
1
+ # -*- encoding: utf-8 -*-
2
+
3
+ Gem::Specification.new do |s|
4
+ s.name = %q{richfile}
5
+ s.version = "0.0.2"
6
+
7
+ s.required_rubygems_version = Gem::Requirement.new(">= 1.2") if s.respond_to? :required_rubygems_version=
8
+ s.authors = ["Till Salzer"]
9
+ s.date = %q{2009-03-25}
10
+ s.description = %q{Extends File objects with some rich instance attributes.}
11
+ s.email = %q{till.salzer@googlemail.com}
12
+ s.extra_rdoc_files = ["lib/richfile/base.rb", "lib/richfile.rb", "MIT-LICENSE", "README.rdoc", "tasks/richfile_tasks.rake"]
13
+ s.files = ["init.rb", "install.rb", "lib/richfile/base.rb", "lib/richfile.rb", "MIT-LICENSE", "Rakefile", "README.rdoc", "specs/richfile_spec.rb", "specs/SimpleDigestTest.txt", "tasks/richfile_tasks.rake", "uninstall.rb", "Manifest", "richfile.gemspec"]
14
+ s.has_rdoc = true
15
+ s.homepage = %q{http://github.com/tsalzer/richfile}
16
+ s.rdoc_options = ["--line-numbers", "--inline-source", "--title", "Richfile", "--main", "README.rdoc"]
17
+ s.require_paths = ["lib"]
18
+ s.rubyforge_project = %q{richfile}
19
+ s.rubygems_version = %q{1.3.1}
20
+ s.summary = %q{Extends File objects with some rich instance attributes.}
21
+
22
+ if s.respond_to? :specification_version then
23
+ current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
24
+ s.specification_version = 2
25
+
26
+ if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
27
+ s.add_development_dependency(%q<rspec>, [">= 0"])
28
+ s.add_development_dependency(%q<rcov>, [">= 0"])
29
+ else
30
+ s.add_dependency(%q<rspec>, [">= 0"])
31
+ s.add_dependency(%q<rcov>, [">= 0"])
32
+ end
33
+ else
34
+ s.add_dependency(%q<rspec>, [">= 0"])
35
+ s.add_dependency(%q<rcov>, [">= 0"])
36
+ end
37
+ end
@@ -0,0 +1,4 @@
1
+ This file is used to test the Message Digest methods.
2
+ However, this file hardly poses a challenge to any
3
+ half-mature digest implementation. It is merely here
4
+ to have a reference point for File.md5 and File.sha1.
@@ -0,0 +1,142 @@
1
+ require 'lib/richfile'
2
+ require "md5"
3
+
4
+ describe OpenSSL, "version" do
5
+ subject { OpenSSL::OPENSSL_VERSION_NUMBER }
6
+ it "should be greater than 0x00908000" do
7
+ subject.should be > 0x00908000
8
+ end
9
+ end
10
+
11
+ describe Richfile::Base, "example SimpleDigestTest.txt" do
12
+ subject { File.new(File.join(File.dirname(__FILE__), "SimpleDigestTest.txt")) }
13
+
14
+ it "should exist" do
15
+ subject.exists?.should == true
16
+ end
17
+
18
+ it "should have a size attribute" do
19
+ subject.should respond_to(:size)
20
+ subject.size.should be > 0
21
+ subject.size.should == File.size(subject)
22
+ end
23
+ it "should have a mtime attribute" do
24
+ subject.should respond_to(:mtime)
25
+ subject.mtime.should == File.mtime(subject)
26
+ end
27
+ it "should have a ctime attribute" do
28
+ subject.should respond_to(:ctime)
29
+ subject.ctime.should == File.ctime(subject)
30
+ end
31
+
32
+ it "should yield the same result as the built-in MD5 function" do
33
+ d = MD5.new
34
+ File.open(File.join(File.dirname(__FILE__), "SimpleDigestTest.txt")) do |f|
35
+ d << f.read
36
+ end
37
+ d.hexdigest.should == subject.md5!
38
+ end
39
+ end
40
+
41
+ { #:dss => nil, - unsupported
42
+ :dss1 => "dee5ba176cb2d1cc7d9a5fc3a2240a37645d6b46",
43
+ :md2 => "8c13cca992d071c02fd338b6c13ab71b",
44
+ :md4 => "3575477e0da66828dcbba890b728d855",
45
+ :md5 => "927f712a74d0cf1281f93874499986c2",
46
+ #:mdc2 => nil, - unsupported
47
+ :ripemd160 => "e9b5c5c6e110022f0a5b493ed1b267c6face4c17",
48
+ :sha => "26f42cf9c6cfe3d95ab924d3b89b210a526a1ea1",
49
+ :sha1 => "dee5ba176cb2d1cc7d9a5fc3a2240a37645d6b46",
50
+ :sha224 => "e69ec20e01d6fac380b727b872dc0e14d1f255d40c3614e075d87de5",
51
+ :sha256 => "204e57f6dc0d8787f87e04347666129a2bd7deddf8949c735a78380b7c2ac65d",
52
+ :sha384 => "a2544e5c3b1a04b38ff0cf8cc29b81bd0fc08d12975949210123e51ae3af1da1538bf3fa6e1b73fc198bc0ac289f891f",
53
+ :sha512 => "137a67bfe730049222f7ac4969d14c3c79ee82d90bd1e223a0217abd8a73f617036222dce542d6243a7b94bc76ff1ee1359f073bb6a116df07c76c2164927800"
54
+ }.each do |cypher, checksum|
55
+ describe Richfile, ".#{cypher} message digest/checksum" do
56
+ subject { File.new(File.join(File.dirname(__FILE__), "SimpleDigestTest.txt")) }
57
+ it "should provide a #{cypher} attribute" do
58
+ subject.should respond_to(cypher)
59
+ subject.send(cypher).should == checksum
60
+ end
61
+ it "should provide a #{cypher}! method" do
62
+ subject.should respond_to("#{cypher}!".to_sym)
63
+ subject.send("#{cypher}!".to_sym).should == checksum
64
+ end
65
+ end
66
+ end
67
+
68
+
69
+ describe Richfile::Base do
70
+ subject { Richfile }
71
+ it "should have a DIGESTS constant with all digests" do
72
+ Richfile::DIGESTS.should == %w(DSS1 MD2 MD4 MD5 RIPEMD160 SHA SHA1 SHA224 SHA256 SHA384 SHA512)
73
+ end
74
+ end
75
+
76
+ describe Richfile::Base, "refresh!" do
77
+ subject { File.new(File.join(File.dirname(__FILE__), "SimpleDigestTest.txt")) }
78
+
79
+ it "should refresh the file size if the size was used" do
80
+ subject.size
81
+ subject.should_receive(:size!).once
82
+ subject.refresh!
83
+ end
84
+ it "should not refresh the file size if the size was not used" do
85
+ subject.should_not_receive(:size!)
86
+ subject.refresh!
87
+ end
88
+
89
+ it "should refresh the MD5 digest if the MD5 digest was used" do
90
+ subject.md5
91
+ subject.should_receive(:md5!).once
92
+ subject.refresh!
93
+ end
94
+ it "should not refresh the MD5 digest if the MD5 digest was not used" do
95
+ subject.should_not_receive(:md5!)
96
+ subject.refresh!
97
+ end
98
+
99
+ it "should refresh the SHA1 digest if the SHA1 digest was used" do
100
+ subject.sha1
101
+ subject.should_receive(:sha1!).once
102
+ subject.refresh!
103
+ end
104
+ it "should not refresh the SHA1 digest if the SHA1 digest was not used" do
105
+ subject.should_not_receive(:sha1!)
106
+ subject.refresh!
107
+ end
108
+
109
+ it "should refresh the SHA512 digest if the SHA512 digest was used" do
110
+ subject.sha512
111
+ subject.should_receive(:sha512!).once
112
+ subject.refresh!
113
+ end
114
+ it "should not refresh the SHA512 digest if the SHA512 digest was not used" do
115
+ subject.should_not_receive(:sha512!)
116
+ subject.refresh!
117
+ end
118
+ end
119
+
120
+ describe Richfile::Base, "refresh_all!" do
121
+ subject { File.new(File.join(File.dirname(__FILE__), "SimpleDigestTest.txt")) }
122
+
123
+ it "should refresh the file size" do
124
+ subject.should_receive(:size!).once
125
+ subject.refresh_all!
126
+ end
127
+
128
+ it "should refresh the MD5 digest" do
129
+ subject.should_receive(:md5!).once
130
+ subject.refresh_all!
131
+ end
132
+
133
+ it "should refresh the SHA1 digest" do
134
+ subject.should_receive(:sha1!).once
135
+ subject.refresh_all!
136
+ end
137
+
138
+ it "should refresh the SHA512 digest" do
139
+ subject.should_receive(:sha512!).once
140
+ subject.refresh_all!
141
+ end
142
+ end
@@ -0,0 +1,34 @@
1
+ require 'rake'
2
+ require 'spec/rake/spectask'
3
+
4
+ ALWAYS_EXCLUDES=['specs/command_spec.rb']
5
+ EXCLUDES=['specsserver_spec.rb'].concat(ALWAYS_EXCLUDES)
6
+
7
+ def filelist(*opts)
8
+ exclude = []
9
+ o = *opts
10
+ if o
11
+ exclude = o[:exclude] if o[:exclude]
12
+ end
13
+ files = FileList['specs/**/*_spec.rb']
14
+ exclude.each do |f|
15
+ files.delete(f)
16
+ end
17
+ files
18
+ end
19
+
20
+ desc "Run all the specs"
21
+ Spec::Rake::SpecTask.new('specs') do |t|
22
+ t.pattern = nil
23
+ t.spec_files = filelist(:exclude => EXCLUDES)
24
+ t.rcov = false
25
+ end
26
+
27
+ desc "Run all specs with RCov"
28
+ Spec::Rake::SpecTask.new('rcov') do |t|
29
+ t.spec_files = filelist(:exclude => EXCLUDES)
30
+ t.rcov = true
31
+ t.rcov_opts = ['--exclude', 'specs/.*,buildlib/project\.rb,buildlib/buildlib\.rb,buildlib/command\.rb']
32
+ end
33
+
34
+ task :default => [:specs]
data/uninstall.rb ADDED
@@ -0,0 +1 @@
1
+ # Uninstall hook code here
metadata ADDED
@@ -0,0 +1,93 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: tsalzer-richfile
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.2
5
+ platform: ruby
6
+ authors:
7
+ - Till Salzer
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+
12
+ date: 2009-03-25 00:00:00 -07:00
13
+ default_executable:
14
+ dependencies:
15
+ - !ruby/object:Gem::Dependency
16
+ name: rspec
17
+ type: :development
18
+ version_requirement:
19
+ version_requirements: !ruby/object:Gem::Requirement
20
+ requirements:
21
+ - - ">="
22
+ - !ruby/object:Gem::Version
23
+ version: "0"
24
+ version:
25
+ - !ruby/object:Gem::Dependency
26
+ name: rcov
27
+ type: :development
28
+ version_requirement:
29
+ version_requirements: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: "0"
34
+ version:
35
+ description: Extends File objects with some rich instance attributes.
36
+ email: till.salzer@googlemail.com
37
+ executables: []
38
+
39
+ extensions: []
40
+
41
+ extra_rdoc_files:
42
+ - lib/richfile/base.rb
43
+ - lib/richfile.rb
44
+ - MIT-LICENSE
45
+ - README.rdoc
46
+ - tasks/richfile_tasks.rake
47
+ files:
48
+ - init.rb
49
+ - install.rb
50
+ - lib/richfile/base.rb
51
+ - lib/richfile.rb
52
+ - MIT-LICENSE
53
+ - Rakefile
54
+ - README.rdoc
55
+ - specs/richfile_spec.rb
56
+ - specs/SimpleDigestTest.txt
57
+ - tasks/richfile_tasks.rake
58
+ - uninstall.rb
59
+ - Manifest
60
+ - richfile.gemspec
61
+ has_rdoc: true
62
+ homepage: http://github.com/tsalzer/richfile
63
+ post_install_message:
64
+ rdoc_options:
65
+ - --line-numbers
66
+ - --inline-source
67
+ - --title
68
+ - Richfile
69
+ - --main
70
+ - README.rdoc
71
+ require_paths:
72
+ - lib
73
+ required_ruby_version: !ruby/object:Gem::Requirement
74
+ requirements:
75
+ - - ">="
76
+ - !ruby/object:Gem::Version
77
+ version: "0"
78
+ version:
79
+ required_rubygems_version: !ruby/object:Gem::Requirement
80
+ requirements:
81
+ - - ">="
82
+ - !ruby/object:Gem::Version
83
+ version: "1.2"
84
+ version:
85
+ requirements: []
86
+
87
+ rubyforge_project: richfile
88
+ rubygems_version: 1.2.0
89
+ signing_key:
90
+ specification_version: 2
91
+ summary: Extends File objects with some rich instance attributes.
92
+ test_files: []
93
+