Permalink
Browse files

TMP > Working attachments support

  • Loading branch information...
karmi committed Jul 22, 2011
1 parent 9ecee04 commit 19613ff48f65b64b2c864b72e2605e790d8eb441
@@ -1,32 +1,56 @@
module Tire
class Attachment
- def initialize(file)
- @file = file
+ def initialize(file_or_hash)
+ case file_or_hash
+ when File
+ @file = file_or_hash
+ when Hash
+ @filename = file_or_hash[:_name] || file_or_hash['_name']
+ @content_type = file_or_hash[:_content_type] || file_or_hash['_content_type']
+ @content = file_or_hash[:content] || file_or_hash['content']
+ @content = @content.unpack('m').to_s
+ end
end
def filename
- File.basename(@file.path)
+ @filename ||= File.basename(@file.path)
end
def content_type
- MIME::Types.type_for(@file.path).first.content_type rescue nil
+ @content_type ||= (MIME::Types.type_for(@file.path).first.content_type rescue nil)
end
- def to_json
+ def content
+ @content ||= begin
+ @file.rewind if @file.eof?
+ @file.read
+ end
+ end
+
+ def to_hash
{
:_name => filename,
:_content_type => content_type,
- :content => encode_base64
- }.to_json
+ :content => encode
+ }
end
- private
+ def to_json
+ to_hash.to_json
+ end
- # Read the file contents and encode it as base64 (MIME_NO_LINEFEEDS)
+ # Encode the file contents as a Base64 (MIME_NO_LINEFEEDS) string
#
- def encode_base64
- @file.rewind if @file.eof?
- [@file.read].pack('m').tr("\n", '')
+ def encode
+ [content].pack('m').tr("\n", '')
+ end
+
+ def decode
+ content.unpack('m').to_s
+ end
+
+ def inspect
+ %Q|<Attachment filename=#{filename}, content_type=#{content_type}, content=#{content.to_s[0..50]}...>|
end
end
View
@@ -13,11 +13,10 @@ def initialize(args={})
self[key.to_sym] = case
when value.is_a?(Hash)
if value['_name'] && value['_content_type']
- # file = File.new(value['_name'], File::CREAT|File::TRUNC|File::RDWR, 0644)
- file << value['content'].unpack('m').to_s
- value['content'] = file
+ Attachment.new(value.to_hash)
+ else
+ self.class.new(value.to_hash)
end
- self.class.new(value.to_hash)
else
value
end
View
@@ -6,12 +6,16 @@ def to_json
def to_indexed_json
# Wrap instances of File in the Attachment class
- # TODO: Do not modify Hash here, wrap Hashes in a Document instance, similarly
+ # TODO: Do not modify Hash here, wrap Hashes in a Document instance
# TODO: Add support for Array of attachments
- self.each_pair do |key,value|
- self.store key, Tire::Attachment.new(value) if value.is_a?(File)
+ self.each_pair do |key,value|
+# p [key, value]
+
+ self.store key, Tire::Attachment.new(value).to_hash if value.is_a?(File)
value.each_pair do |k, v|
- value.store k, Tire::Attachment.new(v) if v.is_a?(File)
+# p [k, v]
+
+ value.store k, Tire::Attachment.new(v).to_hash if v.is_a?(File)
end if value.respond_to?(:each_pair)
end
self.to_json
View
Binary file not shown.
@@ -0,0 +1,76 @@
+require 'test_helper'
+
+module Tire
+
+ class AttachmentsIntegrationTest < Test::Unit::TestCase
+ include Test::Integration
+
+ context "Attachments support" do
+
+ setup do
+ # Tire.configure { logger STDERR, :level => 'debug' }
+ @index = Tire.index 'attachments-tire-test' do
+ delete
+ create :mappings => {
+ :document => {
+ :properties => {
+ :attachment => {
+ :type => 'attachment',
+ :fields => {
+ :_name => { :store => 'yes' },
+ :_content_type => { :store => 'yes' },
+ :content => { :store => 'yes' },
+ :author => { :store => 'yes' },
+ :title => { :store => 'yes' },
+ :date => { :store => 'yes' }
+ }
+ }
+ }
+ }
+ }
+ end
+ end
+
+ teardown do
+ # @index.delete
+ end
+
+ should "store document with attachment" do
+ @index.store :id => 1, :attachment => File.new( fixtures_path.join('test.rtf').to_s )
+ document = @index.retrieve :document, 1
+
+ assert_instance_of Attachment, document.attachment
+ assert_equal 'test.rtf', document.attachment.filename
+ assert_equal 'application/rtf', document.attachment.content_type
+
+ assert_match %r|\{\\rtf1\\ansi\\ansicpg1250|, document.attachment.content
+ end
+
+ should "find the document by metadata" do
+ @index.store :id => 1, :attachment => File.new( fixtures_path.join('test.doc').to_s )
+ @index.refresh
+
+ results = Tire.search @index.name do
+ query { string 'john' }
+ end.results
+
+ assert_equal 1, results.size
+ assert_equal 'test.doc', results.first.attachment.filename
+ end
+
+ should "find the document by metadata with fields highlighted" do
+ @index.store :id => 1, :attachment => File.new( fixtures_path.join('test.doc').to_s )
+ @index.refresh
+
+ results = Tire.search @index.name do
+ query { string 'john' }
+ highlight :author
+ end.results
+
+ assert_match %r|<em>John</em> Smith|, results.first.highlight.author.to_s
+ end
+
+ end
+ end
+
+end
@@ -21,12 +21,28 @@ class AttachmentTest < Test::Unit::TestCase
assert_equal 'application/rtf', @attachment.content_type
end
- should "be serialized into JSON as a base64, MIME_NO_LINEFEEDS encoded string" do
+ should "read the content from file" do
+ assert_equal fixture_file('test.rtf'), @attachment.content
+ end
+
+ should "base64 encode the content" do
+ assert_match /e1xydGYxXGFuc2lcYW5zaWNwZzEyNTBcY29jb2FydGYxMDM4XGNvY29hc3VicnRmMzUw.*/,
+ @attachment.encode
+ end
+
+ should "base64 encode the content when converting to Hash" do
+ assert_match /e1xydGYxXGFuc2lcYW5zaWNwZzEyNTBcY29jb2FydGYxMDM4XGNvY29hc3VicnRmMzUw.*/,
+ @attachment.to_hash[:content]
+ end
+
+ should "be properly serialized into JSON for ElasticSearch" do
assert_instance_of String, @attachment.to_json
- puts @attachment.to_json
hash = MultiJson.decode(@attachment.to_json)
- assert_match /"e1xydGYxXGFuc2lcYW5zaWNwZzEyNTBcY29jb2FydGYxMDM4XGNvY29hc3VicnRmMzUw.*/,
- @attachment.to_json
+
+ assert_equal 'test.rtf', hash['_name']
+ assert_equal 'application/rtf', hash['_content_type']
+ assert_match /e1xydGYxXGFuc2lcYW5zaWNwZzEyNTBcY29jb2FydGYxMDM4XGNvY29hc3VicnRmMzUw.*/,
+ hash['content']
end
end
@@ -35,19 +51,25 @@ class AttachmentTest < Test::Unit::TestCase
setup do
@attachment = Attachment.new :_name => 'test.rtf',
:_content_type => 'application/rtf',
- :content => DATA.read
+ :content => encoded
end
- should "" do
-
+ should "properly set filename and content_type" do
+ assert_equal 'test.rtf', @attachment.filename
+ assert_equal 'application/rtf', @attachment.content_type
+ end
+
+ should "decode the base64 encoded content" do
+ assert_equal fixture_file('test.rtf'), @attachment.content
end
end
end
+ def encoded
+ "e1xydGYxXGFuc2lcYW5zaWNwZzEyNTBcY29jb2FydGYxMDM4XGNvY29hc3VicnRmMzUwCntcZm9udHRibFxmMFxmc3dpc3NcZmNoYXJzZXQwIEhlbHZldGljYTt9CntcY29sb3J0Ymw7XHJlZDI1NVxncmVlbjI1NVxibHVlMjU1O30Ke1xpbmZvCntcdGl0bGUgVGVzdCBSVEYgZG9jdW1lbnR9CntcYXV0aG9yIEpvaG4gU21pdGh9CntcKlxjb21wYW55IE15IE9yZ2FuaXphdGlvbn19XHBhcGVydzExOTAwXHBhcGVyaDE2ODQwXG1hcmdsMTQ0MFxtYXJncjE0NDBcdmlld3c5MDAwXHZpZXdoODQwMFx2aWV3a2luZDAKXHBhcmRcdHg1NjZcdHgxMTMzXHR4MTcwMFx0eDIyNjdcdHgyODM0XHR4MzQwMVx0eDM5NjhcdHg0NTM1XHR4NTEwMlx0eDU2NjlcdHg2MjM2XHR4NjgwM1xxbFxxbmF0dXJhbFxwYXJkaXJuYXR1cmFsCgpcZjBcZnMyNCBcY2YwIFRlc3QgUlRGIGRvY3VtZW50LlwKXApMb3JlbSBpcHN1bSBkb2xvci59"
+ end
+
end
end
-
-__END__
-e1xydGYxXGFuc2lcYW5zaWNwZzEyNTBcY29jb2FydGYxMDM4XGNvY29hc3VicnRmMzUwCntcZm9udHRibFxmMFxmc3dpc3NcZmNoYXJzZXQwIEhlbHZldGljYTt9CntcY29sb3J0Ymw7XHJlZDI1NVxncmVlbjI1NVxibHVlMjU1O30Ke1xpbmZvCntcdGl0bGUgVGVzdCBSVEYgZG9jdW1lbnR9CntcYXV0aG9yIEpvaG4gU21pdGh9CntcKlxjb21wYW55IE15IE9yZ2FuaXphdGlvbn19XHBhcGVydzExOTAwXHBhcGVyaDE2ODQwXG1hcmdsMTQ0MFxtYXJncjE0NDBcdmlld3c5MDAwXHZpZXdoODQwMFx2aWV3a2luZDAKXHBhcmRcdHg1NjZcdHgxMTMzXHR4MTcwMFx0eDIyNjdcdHgyODM0XHR4MzQwMVx0eDM5NjhcdHg0NTM1XHR4NTEwMlx0eDU2NjlcdHg2MjM2XHR4NjgwM1xxbFxxbmF0dXJhbFxwYXJkaXJuYXR1cmFsCgpcZjBcZnMyNCBcY2YwIFRlc3QgUlRGIGRvY3VtZW50LlwKXApMb3JlbSBpcHN1bSBkb2xvci59
@@ -57,8 +57,15 @@ class AlmostHash < Hash; end
assert_equal 'Kafka', @document.author.name
end
- should "base64 decode attachments" do
-
+ should "wrap attachments in an Attachment instance" do
+ @document = Results::Item.new :attachment => { '_name' => 'test.txt',
+ '_content_type' => 'text/plain',
+ 'content' => 'QQ==' }
+
+ assert_instance_of Tire::Attachment, @document.attachment
+ assert_equal 'test.txt', @document.attachment.filename
+ assert_equal 'text/plain', @document.attachment.content_type
+ assert_equal 'A', @document.attachment.content
end
end

0 comments on commit 19613ff

Please sign in to comment.