dragonfly-couch_data_store 1.0.0

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.
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