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 +2 -0
- data/lib/temper/base.rb +54 -0
- data/lib/temper/file.rb +31 -0
- data/lib/temper/stringio.rb +9 -0
- data/lib/temper/version.rb +1 -1
- data/lib/temper.rb +5 -75
- data/spec/examples/sample.txt +9 -0
- data/spec/file/basic_spec.rb +49 -0
- data/spec/spec_helper.rb +13 -0
- data/spec/stringio/basic_spec.rb +34 -0
- data/temper.gemspec +2 -0
- metadata +33 -7
data/.rspec
ADDED
data/lib/temper/base.rb
ADDED
@@ -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
|
data/lib/temper/file.rb
ADDED
@@ -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
|
data/lib/temper/version.rb
CHANGED
data/lib/temper.rb
CHANGED
@@ -3,81 +3,11 @@ require 'stringio'
|
|
3
3
|
require 'mime/types'
|
4
4
|
|
5
5
|
module Temper
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
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
|
data/spec/spec_helper.rb
ADDED
@@ -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
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:
|
4
|
+
hash: 23
|
5
5
|
prerelease:
|
6
6
|
segments:
|
7
|
-
- 0
|
8
|
-
- 9
|
9
7
|
- 1
|
10
|
-
|
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-
|
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:
|