temper 0.9.1 → 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
data/.rspec ADDED
@@ -0,0 +1,2 @@
1
+ --color
2
+ --format d
@@ -0,0 +1,54 @@
1
+ module Temper
2
+ class Base
3
+ attr_accessor :original_filename
4
+ attr_accessor :content_type
5
+
6
+ def initialize(options = {})
7
+ raise RuntimeException, "No @storage set" unless @storage
8
+ self.original_filename = options[:original_filename] || ::File.basename(path)
9
+ self.content_type = options[:content_type] || infer_content_type || "text/plain"
10
+ end
11
+
12
+ def fingerprint
13
+ @fingerprint ||= Digest::MD5.hexdigest(self.read)
14
+ end
15
+
16
+ def respond_to?(*args)
17
+ super or @storage.respond_to?(*args)
18
+ end
19
+
20
+ def method_missing(method_name, *args, &block) #:nodoc:
21
+ @storage.__send__(method_name, *args, &block)
22
+ end
23
+
24
+ private
25
+
26
+ # Infer the MIME-type of the file from the extension.
27
+ def infer_content_type
28
+ types = MIME::Types.type_for(self.original_filename)
29
+ if types.length == 0
30
+ type_from_file_command
31
+ elsif types.length == 1
32
+ types.first.content_type
33
+ else
34
+ iterate_over_array_to_find_best_option(types)
35
+ end
36
+ end
37
+
38
+ def iterate_over_array_to_find_best_option(types)
39
+ types.reject {|type| type.content_type.match(/\/x-/) }.first
40
+ end
41
+
42
+ def type_from_file_command
43
+ # On BSDs, `file` doesn't give a result code of 1 if the file doesn't exist.
44
+ type = (self.original_filename.match(/\.(\w+)$/)[1] rescue "octet-stream").downcase
45
+ mime_type = (run("file", "-b --mime-type :file", :file => self.path).split(':').last.strip rescue "application/x-#{type}")
46
+ mime_type = "application/x-#{type}" if mime_type.match(/\(.*?\)/)
47
+ mime_type
48
+ end
49
+
50
+ def run(command, *arguments)
51
+ Cocaine::CommandLine.new(command, *arguments).run
52
+ end
53
+ end
54
+ end
@@ -0,0 +1,31 @@
1
+ module Temper
2
+ class File < Base
3
+ def initialize(options = {})
4
+ options ||= {}
5
+ @storage = setup_storage(options)
6
+ path = options[:content]
7
+ if path && ::File.exists?(path)
8
+ options[:original_filename] ||= ::File.basename(path)
9
+ end
10
+ super options
11
+ end
12
+
13
+ private
14
+
15
+ def setup_storage(options = {})
16
+ path = options[:content]
17
+ raise ArgumentError, "#{path} file does not exist" if path && !::File.exist?(path)
18
+ Tempfile.new("temperfi").tap do |tempfile|
19
+ tempfile.set_encoding(Encoding::BINARY) if tempfile.respond_to?(:set_encoding)
20
+ tempfile.binmode unless options.key?(:binary) && !options[:binary]
21
+ if path
22
+ ::File.open(path, "rb") do |f|
23
+ tempfile.write(f.read)
24
+ tempfile.flush
25
+ tempfile.rewind
26
+ end
27
+ end
28
+ end
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,9 @@
1
+ module Temper
2
+ class StringIO < Base
3
+ def initialize(options = {})
4
+ @storage = ::StringIO.new(options[:content].to_s)
5
+ options[:original_filename] ||= "stringio.txt"
6
+ super options.merge(options)
7
+ end
8
+ end
9
+ end
@@ -1,3 +1,3 @@
1
1
  module Temper
2
- VERSION = "0.9.1"
2
+ VERSION = "1.0.0"
3
3
  end
data/lib/temper.rb CHANGED
@@ -3,81 +3,11 @@ require 'stringio'
3
3
  require 'mime/types'
4
4
 
5
5
  module Temper
6
- class Base
7
- attr_accessor :original_filename
8
- attr_accessor :content_type
9
-
10
- def initialize(options = {})
11
- raise RuntimeException, "No @storage set" unless @storage
12
- self.original_filename = options[:original_filename] || ::File.basename(path)
13
- self.content_type = infer_content_type || "text/plain"
14
- end
15
-
16
- def fingerprint
17
- @fingerprint ||= Digest::MD5.hexdigest(self.read)
18
- end
19
-
20
- def respond_to?(*args)
21
- super or @storage.respond_to?(*args)
22
- end
23
-
24
- def method_missing(method_name, *args, &block) #:nodoc:
25
- @storage.__send__(method_name, *args, &block)
26
- end
27
-
28
- private
29
-
30
- # Infer the MIME-type of the file from the extension.
31
- def infer_content_type
32
- types = MIME::Types.type_for(self.original_filename)
33
- if types.length == 0
34
- type_from_file_command
35
- elsif types.length == 1
36
- types.first.content_type
37
- else
38
- iterate_over_array_to_find_best_option(types)
39
- end
40
- end
41
-
42
- def iterate_over_array_to_find_best_option(types)
43
- types.reject {|type| type.content_type.match(/\/x-/) }.first
44
- end
45
-
46
- def type_from_file_command
47
- # On BSDs, `file` doesn't give a result code of 1 if the file doesn't exist.
48
- type = (self.original_filename.match(/\.(\w+)$/)[1] rescue "octet-stream").downcase
49
- mime_type = (run("file", "-b --mime-type :file", :file => self.path).split(':').last.strip rescue "application/x-#{type}")
50
- mime_type = "application/x-#{type}" if mime_type.match(/\(.*?\)/)
51
- mime_type
52
- end
53
-
54
- def run(command, *arguments)
55
- Cocaine::CommandLine.new(command, *arguments).run
56
- end
57
-
58
- end
59
-
60
- class File < Base
61
- def initialize(options = {})
62
- path = options[:content]
63
- raise "#{path} file does not exist" if path && !::File.exist?(path)
64
- @storage = Tempfile.new("temperfi")
65
- @storage.set_encoding(Encoding::BINARY) if @storage.respond_to?(:set_encoding)
66
- @storage.binmode unless options.key?(:binary) && !options[:binary]
67
- FileUtils.copy_file(path, @storage.path) if path && !::File.exist?(path)
68
- super options
69
- end
70
- end
71
-
6
+ autoload :Base, 'temper/base'
7
+ autoload :File, 'temper/file'
8
+ autoload :StringIO, 'temper/stringio'
9
+ autoload :VERSION, 'temper/version'
10
+
72
11
  Fi = File unless defined?(Fi)
73
-
74
- class StringIO < Base
75
- def initialize(options = {})
76
- @storage = ::StringIO.new(options[:content].to_s)
77
- options[:original_filename] ||= "stringio.txt"
78
- super options.merge(options)
79
- end
80
- end
81
-
82
12
  Si = StringIO unless defined?(Si)
83
13
  end
@@ -0,0 +1,9 @@
1
+ Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nam posuere fringilla libero, sit amet porttitor mauris interdum id. Vestibulum dictum auctor enim, ac fermentum neque sagittis eu. Sed ut tortor ut nisl placerat sodales. Curabitur vel mauris leo. Phasellus eu nibh velit. Sed a tellus magna, sed bibendum massa. Vestibulum imperdiet dictum fringilla. Quisque feugiat tortor non mi vestibulum venenatis eu viverra augue.
2
+
3
+ Mauris malesuada lobortis nunc, sed facilisis augue tincidunt quis. In scelerisque blandit turpis a mollis. Donec non nulla sit amet diam fermentum volutpat. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Pellentesque tristique, dui non euismod auctor, tellus lectus tempus sem, eu viverra tortor orci nec dolor. In id elit velit, non consectetur neque. Etiam a nibh malesuada felis venenatis accumsan. Proin suscipit ultricies dapibus. Quisque fringilla odio vel orci aliquet et gravida metus rutrum. Ut eu dui at mauris fermentum dapibus at ut urna. Nunc in dui nec massa varius semper a ac ligula. In egestas, eros vel imperdiet pellentesque, libero ligula pretium neque, at tincidunt quam ante ac justo. Mauris ut diam sapien, quis sodales risus. Vestibulum posuere ipsum sit amet nulla consectetur fermentum.
4
+
5
+ Duis in quam sit amet velit tempor congue eleifend nec massa. Fusce euismod scelerisque auctor. Nulla nec risus ut sapien malesuada tempus eu sit amet tellus. Etiam at magna odio. Integer at tellus convallis est ultrices consequat nec eu sapien. Aenean pulvinar orci non metus consequat eget ornare purus sodales. In sit amet ipsum quis purus tempus blandit non eu diam. Etiam hendrerit nisi eu risus euismod ut ultricies ligula vestibulum. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Sed facilisis leo euismod ligula fringilla dictum. Suspendisse potenti. Nulla facilisi. Maecenas vel pulvinar nulla. In hac habitasse platea dictumst. Curabitur aliquet tempus eros. Nullam et dui metus.
6
+
7
+ Praesent sagittis nibh in lorem sagittis vestibulum. Nunc vestibulum lorem vitae turpis hendrerit consequat. Suspendisse potenti. Nunc et lectus quis dui sodales commodo. Donec ante odio, fermentum et rhoncus eu, feugiat vitae ante. Nam rutrum tempor eros sed ornare. Proin diam elit, cursus ac congue eget, vehicula ac ligula. Aliquam erat volutpat. Nulla ac elit sem, non sollicitudin nunc. Ut porta pretium facilisis. Etiam eu magna a urna pulvinar aliquet id id felis. In vel tellus quis nibh ultricies sollicitudin sed eleifend sapien. Integer at quam vitae erat cursus posuere. Aenean ac lectus placerat sem ornare convallis. Donec nulla nulla, accumsan quis pharetra nec, vestibulum nec sapien.
8
+
9
+ Quisque tincidunt mattis tellus et lacinia. Integer non purus augue, sed sollicitudin tortor. Vivamus in neque sem. Quisque quis turpis felis, non condimentum tortor. Etiam quis velit sed felis semper vulputate eu a eros. In cursus condimentum vehicula. Nulla facilisi. Praesent arcu nunc, aliquam et placerat in, placerat nec lorem. Duis fringilla consequat nisl, ultricies semper eros malesuada quis. Phasellus id libero eget quam vehicula pretium sit amet nec lectus. Phasellus lectus sapien, imperdiet et luctus vel, interdum sodales tortor. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Maecenas diam libero, pulvinar vitae varius sit amet, eleifend at lorem. Mauris hendrerit sodales nulla, vel pellentesque mi rutrum id. Pellentesque felis sapien, dictum id feugiat quis, ultricies vel quam. Pellentesque posuere, tellus ornare rhoncus porta, risus lectus pharetra metus, sit amet molestie dolor tortor sed nibh.
@@ -0,0 +1,49 @@
1
+ require 'spec_helper'
2
+
3
+ describe Temper::File do
4
+ let(:sample_text_file){
5
+ File.expand_path("../../examples/sample.txt", __FILE__)
6
+ }
7
+
8
+ context "uses defaults" do
9
+ context "setting an original filename" do
10
+ subject { Temper::File.new(:original_filename => "foo.txt") }
11
+ its(:original_filename) { should == "foo.txt" }
12
+ its(:content_type) { should == "text/plain" }
13
+ end
14
+
15
+ context "with no filename it has a default content type" do
16
+ subject { Temper::File.new }
17
+ its(:content_type) { should == "application/x-octet-stream" }
18
+ end
19
+ end
20
+
21
+ context "uses a file" do
22
+ context "without overriding the filename" do
23
+ subject { Temper::File.new(:content => __FILE__) }
24
+ its(:original_filename) { should == File.basename(__FILE__) }
25
+ its(:content_type) { should == "application/x-ruby" }
26
+ end
27
+
28
+ context "without overriding the filename" do
29
+ subject { Temper::File.new(:original_filename => "foo.txt", :content => __FILE__) }
30
+ its(:original_filename) { should == "foo.txt" }
31
+ its(:content_type) { should == "text/plain" }
32
+ end
33
+
34
+ context "calculates a fingerprint" do
35
+ subject { Temper::File.new(:content => sample_text_file) }
36
+ it "should have the same content as the original file" do
37
+ subject.read.should == File.read(sample_text_file)
38
+ end
39
+ its(:fingerprint) { should == "92974d961d3f7e3f5da0860a97999afa" }
40
+ end
41
+ end
42
+
43
+ it "raises an error with a non-existant file" do
44
+ path = "/foo/bar/blort"
45
+ expect do
46
+ Temper::File.new(:content => path)
47
+ end.to raise_error ArgumentError, "#{path} file does not exist"
48
+ end
49
+ end
@@ -0,0 +1,13 @@
1
+ # This file was generated by the `rspec --init` command. Conventionally, all
2
+ # specs live under a `spec` directory, which RSpec adds to the `$LOAD_PATH`.
3
+ # Require this file using `require "spec_helper.rb"` to ensure that it is only
4
+ # loaded once.
5
+ #
6
+ # See http://rubydoc.info/gems/rspec-core/RSpec/Core/Configuration
7
+ RSpec.configure do |config|
8
+ config.treat_symbols_as_metadata_keys_with_true_values = true
9
+ config.run_all_when_everything_filtered = true
10
+ config.filter_run :focus
11
+ end
12
+
13
+ require File.expand_path("../../lib/temper", __FILE__)
@@ -0,0 +1,34 @@
1
+ require 'spec_helper'
2
+
3
+ describe Temper::StringIO do
4
+ context "empty content" do
5
+ subject { Temper::StringIO.new}
6
+ its(:original_filename) { should == "stringio.txt" }
7
+ its(:content_type) { should == "text/plain" }
8
+ end
9
+
10
+ context "custom filename" do
11
+ subject { Temper::StringIO.new(:original_filename => "foo.txt") }
12
+ its(:original_filename) { should == "foo.txt" }
13
+ its(:content_type) { should == "text/plain" }
14
+ end
15
+
16
+ context "custom content_type" do
17
+ subject { Temper::StringIO.new(:content_type => "text/html") }
18
+ its(:original_filename) { should == "stringio.txt" }
19
+ its(:content_type) { should == "text/html" }
20
+ end
21
+
22
+ context "should calculate fingerprint" do
23
+ context "empty content" do
24
+ subject { Temper::StringIO.new() }
25
+ its(:fingerprint) { should == "d41d8cd98f00b204e9800998ecf8427e" }
26
+ end
27
+
28
+ context "normal content" do
29
+ subject { Temper::StringIO.new(:content => "foo") }
30
+ its(:fingerprint) { should == "acbd18db4cc2f85cedef654fccc4a4d8" }
31
+ end
32
+ end
33
+
34
+ end
data/temper.gemspec CHANGED
@@ -17,4 +17,6 @@ Gem::Specification.new do |gem|
17
17
 
18
18
  gem.add_runtime_dependency "mime-types"
19
19
  gem.add_runtime_dependency "cocaine"
20
+
21
+ gem.add_development_dependency "rspec", "> 2.0"
20
22
  end
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: temper
3
3
  version: !ruby/object:Gem::Version
4
- hash: 57
4
+ hash: 23
5
5
  prerelease:
6
6
  segments:
7
- - 0
8
- - 9
9
7
  - 1
10
- version: 0.9.1
8
+ - 0
9
+ - 0
10
+ version: 1.0.0
11
11
  platform: ruby
12
12
  authors:
13
13
  - Andrew Eberbach
@@ -15,7 +15,7 @@ autorequire:
15
15
  bindir: bin
16
16
  cert_chain: []
17
17
 
18
- date: 2012-05-28 00:00:00 Z
18
+ date: 2012-06-06 00:00:00 Z
19
19
  dependencies:
20
20
  - !ruby/object:Gem::Dependency
21
21
  name: mime-types
@@ -45,6 +45,21 @@ dependencies:
45
45
  version: "0"
46
46
  type: :runtime
47
47
  version_requirements: *id002
48
+ - !ruby/object:Gem::Dependency
49
+ name: rspec
50
+ prerelease: false
51
+ requirement: &id003 !ruby/object:Gem::Requirement
52
+ none: false
53
+ requirements:
54
+ - - ">"
55
+ - !ruby/object:Gem::Version
56
+ hash: 3
57
+ segments:
58
+ - 2
59
+ - 0
60
+ version: "2.0"
61
+ type: :development
62
+ version_requirements: *id003
48
63
  description: A gem for a slightly smarter temporary file and temporary directory maintenance
49
64
  email:
50
65
  - andrew@ebertech.ca
@@ -56,12 +71,20 @@ extra_rdoc_files: []
56
71
 
57
72
  files:
58
73
  - .gitignore
74
+ - .rspec
59
75
  - Gemfile
60
76
  - LICENSE
61
77
  - README.md
62
78
  - Rakefile
63
79
  - lib/temper.rb
80
+ - lib/temper/base.rb
81
+ - lib/temper/file.rb
82
+ - lib/temper/stringio.rb
64
83
  - lib/temper/version.rb
84
+ - spec/examples/sample.txt
85
+ - spec/file/basic_spec.rb
86
+ - spec/spec_helper.rb
87
+ - spec/stringio/basic_spec.rb
65
88
  - temper.gemspec
66
89
  homepage: https://github.com/ebertech/temper
67
90
  licenses: []
@@ -96,6 +119,9 @@ rubygems_version: 1.8.21
96
119
  signing_key:
97
120
  specification_version: 3
98
121
  summary: Combines the best parts of Upfile from paperclip and Rack::Multipart::UploadedFile from rack.
99
- test_files: []
100
-
122
+ test_files:
123
+ - spec/examples/sample.txt
124
+ - spec/file/basic_spec.rb
125
+ - spec/spec_helper.rb
126
+ - spec/stringio/basic_spec.rb
101
127
  has_rdoc: