paperclip-gridfs 1.0
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +18 -0
- data/README.md +45 -0
- data/lib/paperclip-gridfs.rb +1 -0
- data/lib/paperclip-gridfs/version.rb +5 -0
- data/lib/paperclip/storage/gridfs.rb +95 -0
- data/paperclip-gridfs.gemspec +25 -0
- metadata +82 -0
data/.gitignore
ADDED
data/README.md
ADDED
@@ -0,0 +1,45 @@
|
|
1
|
+
paperclip-gridfs
|
2
|
+
================
|
3
|
+
|
4
|
+
A fork of gmontard/paperclip-gridfs (which was apparently a fork of kristianmandrup/paperclip), however no fork reference was wanted to thoughtbot/paperclip
|
5
|
+
|
6
|
+
## Usage
|
7
|
+
|
8
|
+
There are two ways of configuring the GridFS connection. Either you create a connection or you reuse an existing connection.
|
9
|
+
|
10
|
+
Creating a connection looks something like this:
|
11
|
+
|
12
|
+
class User
|
13
|
+
include MongoMapper::Document
|
14
|
+
include Paperclip::Glue
|
15
|
+
|
16
|
+
key :avatar_file_name, String
|
17
|
+
key :avatar_content_type, String
|
18
|
+
has_attached_file :avatar, :storage => :gridfs, :gridfs => {:database => 'avatars', :host => 'test.com'}, :path => "avatars/:style/:filename", :url => "/avatars/:style/:filename"
|
19
|
+
end
|
20
|
+
|
21
|
+
When you already have a Mongo connection object (for example through Mongoid or MongoMapper) you can also reuse this connection:
|
22
|
+
|
23
|
+
class User
|
24
|
+
include MongoMapper::Document
|
25
|
+
include Paperclip::Glue
|
26
|
+
|
27
|
+
key :avatar_file_name, String
|
28
|
+
key :avatar_content_type, String
|
29
|
+
has_attached_file :avatar, :storage => :gridfs, :gridfs => {:database => MongoMapper.database}, :path => "avatars/:style/:filename", :url => "/avatars/:style/:filename"
|
30
|
+
end
|
31
|
+
|
32
|
+
However, one then needs to also tie the URL's inside the app with the GridFS attachments (which can be viewed with `.to_file(style)`, outputting the binary contents, same as File.read). An example done in Sinatra, for the above class:
|
33
|
+
|
34
|
+
# Get user avatar
|
35
|
+
get '/avatars/:style/:id.:extension' do
|
36
|
+
if params[:id] != 'missing'
|
37
|
+
u = User.first(:id => params[:id])
|
38
|
+
content_type u.avatar.content_type
|
39
|
+
u.avatar.to_file(params[:style])
|
40
|
+
else
|
41
|
+
content_type 'image/png'
|
42
|
+
File.open('public/avatars/missing.png').read #haxx
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
@@ -0,0 +1 @@
|
|
1
|
+
require 'paperclip/storage/gridfs'
|
@@ -0,0 +1,95 @@
|
|
1
|
+
module Paperclip
|
2
|
+
module Storage
|
3
|
+
# MongoDB's GridFS storage system (http://www.mongodb.org/display/DOCS/GridFS) uses
|
4
|
+
# a chunking strategy to store files in a mongodb database.
|
5
|
+
# Specific options for GridFS:
|
6
|
+
# * +gridfs_credentials+: Similar to +s3_credentials+, this can be a path, a File, or
|
7
|
+
# a Hash. Keys are as follows:
|
8
|
+
# * +database+: the name of the MongoDB database to connect to. This can also be
|
9
|
+
# a +Mongo::DB+ object, in which case that connection will be used, and other
|
10
|
+
# credentials will be ignored.
|
11
|
+
# * +host+: defaults to +localhost+
|
12
|
+
# * +username+ and +password+: optional authentication for the database server.
|
13
|
+
#
|
14
|
+
# Note that, because files stored using the +:gridfs+ storage module are stored
|
15
|
+
# within the database rather than the file system, you'll need to work out a method
|
16
|
+
# to extract the file data to serve it over HTTP. This is pretty trivial using
|
17
|
+
# Rails Metal.
|
18
|
+
|
19
|
+
module Gridfs
|
20
|
+
def self.extended base
|
21
|
+
begin
|
22
|
+
require 'mongo'
|
23
|
+
rescue LoadError => e
|
24
|
+
e.message << " (You may need to install the mongo gem)"
|
25
|
+
raise e
|
26
|
+
end
|
27
|
+
|
28
|
+
base.instance_eval do
|
29
|
+
@gridfs_connection = get_database_connection(parse_credentials(@options[:gridfs]))
|
30
|
+
@gridfs = Mongo::GridFileSystem.new(@gridfs_connection)
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
def parse_credentials creds
|
35
|
+
creds = find_credentials(creds).stringify_keys
|
36
|
+
env = Object.const_defined?(:Rails) ? Rails.env : nil
|
37
|
+
(creds[env] || creds).symbolize_keys
|
38
|
+
end
|
39
|
+
|
40
|
+
def exists? style = default_style
|
41
|
+
if original_filename
|
42
|
+
!!@gridfs.exist?(:filename => path(style))
|
43
|
+
else
|
44
|
+
false
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
# Returns a binary representation of the data of the file assigned to the given style
|
49
|
+
def to_file style = default_style
|
50
|
+
@queued_for_write[style] || (@gridfs.open(path(style), 'r') if exists?(style))
|
51
|
+
end
|
52
|
+
|
53
|
+
def flush_writes #:nodoc:
|
54
|
+
@queued_for_write.each do |style, file|
|
55
|
+
log("saving #{path(style)}")
|
56
|
+
@gridfs.open(path(style), 'w', :content_type => content_type) do |f|
|
57
|
+
f.write file.read
|
58
|
+
end
|
59
|
+
end
|
60
|
+
after_flush_writes # allows attachment to clean up temp files
|
61
|
+
@queued_for_write = {}
|
62
|
+
end
|
63
|
+
|
64
|
+
def flush_deletes #:nodoc:
|
65
|
+
@queued_for_delete.each do |path|
|
66
|
+
log("deleting #{path}")
|
67
|
+
@gridfs.delete(path)
|
68
|
+
end
|
69
|
+
@queued_for_delete = []
|
70
|
+
end
|
71
|
+
|
72
|
+
private
|
73
|
+
|
74
|
+
def get_database_connection creds
|
75
|
+
return creds[:database] if creds[:database].is_a? Mongo::DB
|
76
|
+
db = Mongo::Connection.new(creds[:host] || Mongo::Connection::DEFAULT_HOST, creds[:port] || Mongo::Connection::DEFAULT_PORT).db(creds[:database])
|
77
|
+
db.authenticate(creds[:username], creds[:password]) if creds[:username] && creds[:password]
|
78
|
+
return db
|
79
|
+
end
|
80
|
+
|
81
|
+
def find_credentials creds
|
82
|
+
case creds
|
83
|
+
when File
|
84
|
+
YAML::load(ERB.new(File.read(creds.path)).result)
|
85
|
+
when String, Pathname
|
86
|
+
YAML::load(ERB.new(File.read(creds)).result)
|
87
|
+
when Hash
|
88
|
+
creds
|
89
|
+
else
|
90
|
+
raise ArgumentError, "Credentials are not a path, file or hash."
|
91
|
+
end
|
92
|
+
end
|
93
|
+
end
|
94
|
+
end
|
95
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
# encoding: UTF-8
|
2
|
+
$LOAD_PATH << File.join(File.dirname(__FILE__), 'lib')
|
3
|
+
require 'paperclip-gridfs/version'
|
4
|
+
|
5
|
+
spec = Gem::Specification.new do |s|
|
6
|
+
s.name = 'paperclip-gridfs'
|
7
|
+
s.version = Paperclip::GridFS::VERSION
|
8
|
+
s.authors = ['Blaž Hrastnik']
|
9
|
+
s.email = 'blaz.hrast@gmail.com'
|
10
|
+
s.homepage = 'https://github.com/archSeer/paperclip-gridfs'
|
11
|
+
s.description = 'Paperclip extension to make it support GridFS'
|
12
|
+
s.summary = 'Paperclip GridFS support'
|
13
|
+
|
14
|
+
s.files = `git ls-files`.split("\n")
|
15
|
+
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
16
|
+
s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
17
|
+
s.require_paths = ["lib"]
|
18
|
+
|
19
|
+
#s.has_rdoc = true
|
20
|
+
#s.extra_rdoc_files = Dir["README*"]
|
21
|
+
#s.rdoc_options << '--line-numbers' << '--inline-source'
|
22
|
+
|
23
|
+
s.add_dependency 'paperclip'
|
24
|
+
s.add_dependency 'mongo', '>=1.1.4'
|
25
|
+
end
|
metadata
ADDED
@@ -0,0 +1,82 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: paperclip-gridfs
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: '1.0'
|
5
|
+
prerelease:
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Blaž Hrastnik
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2012-11-26 00:00:00.000000000 Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: paperclip
|
16
|
+
requirement: !ruby/object:Gem::Requirement
|
17
|
+
none: false
|
18
|
+
requirements:
|
19
|
+
- - ! '>='
|
20
|
+
- !ruby/object:Gem::Version
|
21
|
+
version: '0'
|
22
|
+
type: :runtime
|
23
|
+
prerelease: false
|
24
|
+
version_requirements: !ruby/object:Gem::Requirement
|
25
|
+
none: false
|
26
|
+
requirements:
|
27
|
+
- - ! '>='
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
version: '0'
|
30
|
+
- !ruby/object:Gem::Dependency
|
31
|
+
name: mongo
|
32
|
+
requirement: !ruby/object:Gem::Requirement
|
33
|
+
none: false
|
34
|
+
requirements:
|
35
|
+
- - ! '>='
|
36
|
+
- !ruby/object:Gem::Version
|
37
|
+
version: 1.1.4
|
38
|
+
type: :runtime
|
39
|
+
prerelease: false
|
40
|
+
version_requirements: !ruby/object:Gem::Requirement
|
41
|
+
none: false
|
42
|
+
requirements:
|
43
|
+
- - ! '>='
|
44
|
+
- !ruby/object:Gem::Version
|
45
|
+
version: 1.1.4
|
46
|
+
description: Paperclip extension to make it support GridFS
|
47
|
+
email: blaz.hrast@gmail.com
|
48
|
+
executables: []
|
49
|
+
extensions: []
|
50
|
+
extra_rdoc_files: []
|
51
|
+
files:
|
52
|
+
- .gitignore
|
53
|
+
- README.md
|
54
|
+
- lib/paperclip-gridfs.rb
|
55
|
+
- lib/paperclip-gridfs/version.rb
|
56
|
+
- lib/paperclip/storage/gridfs.rb
|
57
|
+
- paperclip-gridfs.gemspec
|
58
|
+
homepage: https://github.com/archSeer/paperclip-gridfs
|
59
|
+
licenses: []
|
60
|
+
post_install_message:
|
61
|
+
rdoc_options: []
|
62
|
+
require_paths:
|
63
|
+
- lib
|
64
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
65
|
+
none: false
|
66
|
+
requirements:
|
67
|
+
- - ! '>='
|
68
|
+
- !ruby/object:Gem::Version
|
69
|
+
version: '0'
|
70
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
71
|
+
none: false
|
72
|
+
requirements:
|
73
|
+
- - ! '>='
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '0'
|
76
|
+
requirements: []
|
77
|
+
rubyforge_project:
|
78
|
+
rubygems_version: 1.8.24
|
79
|
+
signing_key:
|
80
|
+
specification_version: 3
|
81
|
+
summary: Paperclip GridFS support
|
82
|
+
test_files: []
|