dragonfly-couch_data_store 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 7ac3670ecae746c881b2f5267c043a40675fb702
4
+ data.tar.gz: c8d2b02a1d5a31ce2d37f70f1ccbb121727e5b82
5
+ SHA512:
6
+ metadata.gz: 0b99e0cf0b098df6159e968ff201f8ad9982cb733c113cddb3a49c19212f227c71e37a50ab7628391bcfaa3d279bb77286b12b43882ec0cd88318acbd34ac4c8
7
+ data.tar.gz: 4725d751fb33455ad332b8d580ed082438d4964221567740513c1441b3aa50ce092c4485d6f4a671c3b7c41b54ee7eb3d916f9c39164a9aa6fd2b1f90767fa8d
data/.gitignore ADDED
@@ -0,0 +1,19 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ Gemfile.lock
7
+ InstalledFiles
8
+ _yardoc
9
+ coverage
10
+ doc/
11
+ lib/bundler/man
12
+ pkg
13
+ rdoc
14
+ spec/reports
15
+ test/tmp
16
+ test/version_tmp
17
+ tmp
18
+ dragonfly.log
19
+
data/Gemfile ADDED
@@ -0,0 +1,3 @@
1
+ source 'https://rubygems.org'
2
+ gemspec
3
+
data/LICENSE.txt ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2013 Mark Evans
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,51 @@
1
+ # Dragonfly::CouchDataStore
2
+
3
+ Couch data store for use with the [Dragonfly](http://github.com/markevans/dragonfly) gem.
4
+
5
+ ## Gemfile
6
+
7
+ ```ruby
8
+ gem 'dragonfly-couch_data_store'
9
+ ```
10
+
11
+ ## Usage
12
+
13
+ In your dragonfly config block (with default options):
14
+
15
+ ```ruby
16
+ Dragonfly.app.configure do
17
+ # ...
18
+
19
+ datastore :couch
20
+
21
+ # ...
22
+ end
23
+ ```
24
+
25
+ Or with options:
26
+
27
+ ```ruby
28
+ datastore :couch, username: 'potatoman', password: 'spudulike'
29
+ ```
30
+
31
+ ### Available options
32
+
33
+ ```ruby
34
+ :host # default 'localhost'
35
+ :port # default 5984
36
+ :database # default 'dragonfly'
37
+ :username # not needed in 'admin party' mode
38
+ :password # not needed in 'admin party' mode
39
+ ```
40
+
41
+ ### Serving directly from Couch
42
+
43
+ ```ruby
44
+ Dragonfly.app.remote_url_for('some/uid')
45
+ ```
46
+
47
+ or
48
+
49
+ ```ruby
50
+ my_model.attachment.remote_url
51
+ ```
data/Rakefile ADDED
@@ -0,0 +1 @@
1
+ require "bundler/gem_tasks"
@@ -0,0 +1,25 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'dragonfly/couch_data_store/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "dragonfly-couch_data_store"
8
+ spec.version = Dragonfly::CouchDataStore::VERSION
9
+ spec.authors = ["Mark Evans"]
10
+ spec.email = ["mark@new-bamboo.co.uk"]
11
+ spec.description = %q{Couch data store for Dragonfly}
12
+ spec.summary = %q{Data store for storing content (e.g. images) handled with the Dragonfly gem in a couch database}
13
+ spec.homepage = ""
14
+ spec.license = "MIT"
15
+
16
+ spec.files = `git ls-files`.split($/)
17
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
18
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
19
+ spec.require_paths = ["lib"]
20
+
21
+ spec.add_runtime_dependency "dragonfly", "~> 1.0"
22
+ spec.add_runtime_dependency "couchrest"
23
+ spec.add_development_dependency "rspec", "~> 2.0"
24
+ end
25
+
@@ -0,0 +1,82 @@
1
+ require 'couchrest'
2
+ require 'dragonfly'
3
+
4
+ Dragonfly::App.register_datastore(:couch){ Dragonfly::CouchDataStore }
5
+
6
+ module Dragonfly
7
+ class CouchDataStore
8
+
9
+ include Serializer
10
+
11
+ def initialize(opts={})
12
+ @host = opts[:host] || 'localhost'
13
+ @port = opts[:port] || '5984'
14
+ @database = opts[:database] || 'dragonfly'
15
+ @username = opts[:username]
16
+ @password = opts[:password]
17
+ end
18
+
19
+ attr_reader :host, :port, :database, :username, :password
20
+
21
+ def write(content, opts={})
22
+ name = content.name || 'file'
23
+
24
+ content.file do |f|
25
+ doc = CouchRest::Document.new(:meta => content.meta)
26
+ response = db.save_doc(doc)
27
+ doc.put_attachment(name, f.dup, :content_type => content.mime_type)
28
+ form_uid(response['id'], name)
29
+ end
30
+ end
31
+
32
+ def read(uid)
33
+ doc_id, attachment = parse_uid(uid)
34
+ doc = db.get(doc_id)
35
+ [doc.fetch_attachment(attachment), extract_meta(doc)]
36
+ rescue RestClient::ResourceNotFound => e
37
+ nil
38
+ end
39
+
40
+ def destroy(uid)
41
+ doc_id, attachment = parse_uid(uid)
42
+ doc = db.get(doc_id)
43
+ db.delete_doc(doc)
44
+ rescue RestClient::ResourceNotFound => e
45
+ Dragonfly.warn("#{self.class.name} destroy error: #{e}")
46
+ end
47
+
48
+ def db
49
+ @db ||= begin
50
+ url = "http://#{auth}#{host}:#{port}"
51
+ CouchRest.new(url).database!(database)
52
+ end
53
+ end
54
+
55
+ def url_for(uid, opts={})
56
+ doc_id, attachment = parse_uid(uid)
57
+ "http://#{host}:#{port}/#{database}/#{doc_id}/#{attachment}"
58
+ end
59
+
60
+ private
61
+
62
+ def auth
63
+ username ? "#{username}:#{password}@" : nil
64
+ end
65
+
66
+ def form_uid(doc_id, attachment)
67
+ "#{doc_id}/#{attachment}"
68
+ end
69
+
70
+ def parse_uid(uid)
71
+ doc_id, attachment = uid.split('/')
72
+ [doc_id, (attachment || 'file')]
73
+ end
74
+
75
+ def extract_meta(doc)
76
+ meta = doc['meta']
77
+ meta = Utils.stringify_keys(marshal_b64_decode(meta)) if meta.is_a?(String) # Deprecated encoded meta
78
+ meta
79
+ end
80
+
81
+ end
82
+ end
@@ -0,0 +1,5 @@
1
+ module Dragonfly
2
+ module CouchDataStore
3
+ VERSION = "1.0.0"
4
+ end
5
+ end
@@ -0,0 +1,80 @@
1
+ # encoding: utf-8
2
+ require 'spec_helper'
3
+ require 'net/http'
4
+ require 'uri'
5
+ require 'dragonfly/couch_data_store'
6
+ require 'dragonfly/spec/data_store_examples'
7
+
8
+ describe Dragonfly::CouchDataStore do
9
+
10
+ before(:each) do
11
+ @data_store = Dragonfly::CouchDataStore.new(:database => "dragonfly_test")
12
+ end
13
+
14
+ it_should_behave_like 'data_store'
15
+
16
+ let (:app) { Dragonfly.app }
17
+ let (:content) { Dragonfly::Content.new(app, "gollum") }
18
+ let (:new_content) { Dragonfly::Content.new(app) }
19
+
20
+ describe "configuring the app" do
21
+ it "can be configured with a symbol" do
22
+ app.configure do
23
+ datastore :couch
24
+ end
25
+ app.datastore.should be_a(Dragonfly::CouchDataStore)
26
+ end
27
+ end
28
+
29
+ describe "url_for" do
30
+ it "should give the correct url" do
31
+ @data_store.url_for('asd7fas9df/thing.txt').should == 'http://localhost:5984/dragonfly_test/asd7fas9df/thing.txt'
32
+ end
33
+
34
+ it "should assume the attachment is called 'file' if not given" do
35
+ @data_store.url_for('asd7fas9df').should == 'http://localhost:5984/dragonfly_test/asd7fas9df/file'
36
+ end
37
+ end
38
+
39
+ describe "serving from couchdb" do
40
+
41
+ def get_content(url)
42
+ uri = URI.parse(url)
43
+ Net::HTTP.start(uri.host, uri.port) {|http|
44
+ http.get(uri.path)
45
+ }
46
+ end
47
+
48
+ it "serves with the correct data type (taken from ext)" do
49
+ content.name = 'doogie.png'
50
+ uid = @data_store.write(content)
51
+ response = get_content(@data_store.url_for(uid))
52
+ response.body.should == 'gollum'
53
+ response['Content-Type'].should == 'image/png'
54
+ end
55
+
56
+ end
57
+
58
+ describe "already stored stuff" do
59
+ def store_pdf(meta)
60
+ doc = CouchRest::Document.new(:meta => meta)
61
+ doc_id = @data_store.db.save_doc(doc)['id']
62
+ doc.put_attachment("pdf", "PDF data here")
63
+ doc_id
64
+ end
65
+
66
+ it "still works" do
67
+ doc_id = store_pdf('some' => 'cool things')
68
+ new_content.update(*@data_store.read("#{doc_id}/pdf"))
69
+ new_content.data.should == "PDF data here"
70
+ new_content.meta['some'].should == 'cool things'
71
+ end
72
+
73
+ it "still works when meta was stored as a marshal dumped hash (but stringifies its keys)" do
74
+ doc_id = store_pdf(Dragonfly::Serializer.marshal_b64_encode(:some => 'shizzle'))
75
+ new_content.update(*@data_store.read("#{doc_id}/pdf"))
76
+ new_content.meta['some'].should == 'shizzle'
77
+ end
78
+ end
79
+
80
+ end
@@ -0,0 +1,7 @@
1
+ RSpec.configure do |config|
2
+ config.treat_symbols_as_metadata_keys_with_true_values = true
3
+ config.run_all_when_everything_filtered = true
4
+ config.filter_run :focus
5
+ config.order = 'random'
6
+ end
7
+
metadata ADDED
@@ -0,0 +1,99 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: dragonfly-couch_data_store
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.0.0
5
+ platform: ruby
6
+ authors:
7
+ - Mark Evans
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2013-11-25 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: dragonfly
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ~>
18
+ - !ruby/object:Gem::Version
19
+ version: '1.0'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ~>
25
+ - !ruby/object:Gem::Version
26
+ version: '1.0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: couchrest
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - '>='
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - '>='
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: rspec
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ~>
46
+ - !ruby/object:Gem::Version
47
+ version: '2.0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ~>
53
+ - !ruby/object:Gem::Version
54
+ version: '2.0'
55
+ description: Couch data store for Dragonfly
56
+ email:
57
+ - mark@new-bamboo.co.uk
58
+ executables: []
59
+ extensions: []
60
+ extra_rdoc_files: []
61
+ files:
62
+ - .gitignore
63
+ - Gemfile
64
+ - LICENSE.txt
65
+ - README.md
66
+ - Rakefile
67
+ - dragonfly-couch_data_store.gemspec
68
+ - lib/dragonfly/couch_data_store.rb
69
+ - lib/dragonfly/couch_data_store/version.rb
70
+ - spec/couch_data_store_spec.rb
71
+ - spec/spec_helper.rb
72
+ homepage: ''
73
+ licenses:
74
+ - MIT
75
+ metadata: {}
76
+ post_install_message:
77
+ rdoc_options: []
78
+ require_paths:
79
+ - lib
80
+ required_ruby_version: !ruby/object:Gem::Requirement
81
+ requirements:
82
+ - - '>='
83
+ - !ruby/object:Gem::Version
84
+ version: '0'
85
+ required_rubygems_version: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - '>='
88
+ - !ruby/object:Gem::Version
89
+ version: '0'
90
+ requirements: []
91
+ rubyforge_project:
92
+ rubygems_version: 2.1.11
93
+ signing_key:
94
+ specification_version: 4
95
+ summary: Data store for storing content (e.g. images) handled with the Dragonfly gem
96
+ in a couch database
97
+ test_files:
98
+ - spec/couch_data_store_spec.rb
99
+ - spec/spec_helper.rb