mongoid_grid 0.0.4

Sign up to get free protection for your applications and to get access to all the features.
data/README.txt ADDED
@@ -0,0 +1,61 @@
1
+ Mongoid::Grid / Rack::Grid
2
+
3
+ Mongoid::Grid is a plugin for mongoid that uses GridFS. Heavily inspired
4
+ by grip (http://github.com/jnunemaker/grip)
5
+
6
+ Rack::Grid is used to serve a GridFS file from rack. Mostly copied
7
+ from http://github.com/skinandbones/rack-gridfs
8
+
9
+ Download the source at
10
+ http://github.com/dusty/mongoid_grid
11
+
12
+
13
+ Installation
14
+
15
+ Put the libraries in your project however you want.
16
+
17
+ # gem install mongoid_grid
18
+
19
+ Or, make your own gem.
20
+
21
+ # git clone http://github.com/dusty/mongoid_grid
22
+ # cd mongoid_grid
23
+ # gem build mongoid_grid.gemspec
24
+
25
+ Then require the libraries you want to use.
26
+
27
+ require 'mongoid/grid'
28
+ require 'rack/grid'
29
+
30
+
31
+ Usage
32
+
33
+ class Monkey
34
+ include Mongoid::Document
35
+ include Mongoid::Grid
36
+ field :name
37
+ attachment :image
38
+ end
39
+
40
+ m = Monkey.create(:name => 'name')
41
+
42
+ # To add an attachment
43
+ m.image = File.open('/tmp/me.jpg')
44
+ m.save
45
+
46
+ # To remove an attachment
47
+ m.image = nil
48
+ m.save
49
+
50
+ # To get the attachment
51
+ m.image.read
52
+
53
+ # To use Rack::Grid with Sinatra
54
+
55
+ configure do
56
+ use Rack::Grid, :database => 'my_db'
57
+ end
58
+
59
+ <img src="<%= m.image_url %>" alt="<%= m.image_name %>" />
60
+
61
+
@@ -0,0 +1,169 @@
1
+ require 'mime/types'
2
+ require 'mongoid'
3
+ module Mongoid
4
+ module Grid
5
+
6
+ def self.included(base)
7
+ base.send(:extend, ClassMethods)
8
+ base.send(:include, InstanceMethods)
9
+ end
10
+
11
+ module ClassMethods
12
+
13
+ ##
14
+ # Declare an attachment for the object
15
+ #
16
+ # eg: attachment :image
17
+ def attachment(name,prefix='grid')
18
+ ##
19
+ # Callbacks to handle the attachment saving and deleting
20
+ after_save :create_attachments
21
+ after_save :delete_attachments
22
+ after_destroy :destroy_attachments
23
+
24
+ ##
25
+ # Fields for the attachment.
26
+ #
27
+ # Only the _id is really needed, the others are helpful cached
28
+ # so you don't need to hit GridFS
29
+ field "#{name}_id".to_sym, :type => BSON::ObjectID
30
+ field "#{name}_name".to_sym, :type => String
31
+ field "#{name}_size".to_sym, :type => Integer
32
+ field "#{name}_type".to_sym, :type => String
33
+
34
+ ##
35
+ # Add this name to the attachment_types
36
+ attachment_types.push(name).uniq!
37
+
38
+ ##
39
+ # Return the GridFS object.
40
+ # eg: image.filename, image.read
41
+ define_method(name) do
42
+ grid.get(attributes["#{name}_id"]) if attributes["#{name}_id"]
43
+ end
44
+
45
+ ##
46
+ # Create a method to set the attachment
47
+ # eg: object.image = File.open('/tmp/somefile.jpg')
48
+ define_method("#{name}=") do |file|
49
+ if file.respond_to?(:read)
50
+ send(:create_attachment, name, file)
51
+ else
52
+ send(:delete_attachment, name, send("#{name}_id"))
53
+ end
54
+ end
55
+
56
+ ##
57
+ # Return the relative URL to the file for use with Rack::Grid
58
+ # eg: /grid/4ba69fde8c8f369a6e000003/somefile.png
59
+ define_method("#{name}_url") do
60
+ _id = send("#{name}_id")
61
+ _name = send("#{name}_name")
62
+ ["/#{prefix}", _id, _name].join('/') if _id && _name
63
+ end
64
+
65
+ end
66
+
67
+ ##
68
+ # Accessor to GridFS
69
+ def grid
70
+ @grid ||= Mongo::Grid.new(Mongoid.database)
71
+ end
72
+
73
+ ##
74
+ # All the attachments types for this class
75
+ def attachment_types
76
+ @attachment_types ||= []
77
+ end
78
+
79
+ end
80
+
81
+ module InstanceMethods
82
+
83
+ private
84
+ ##
85
+ # Accessor to GridFS
86
+ def grid
87
+ @grid ||= self.class.grid
88
+ end
89
+
90
+ ##
91
+ # Holds queue of attachments to create
92
+ def create_attachment_queue
93
+ @create_attachment_queue ||= {}
94
+ end
95
+
96
+ ##
97
+ # Holds queue of attachments to delete
98
+ def delete_attachment_queue
99
+ @delete_attachment_queue ||= {}
100
+ end
101
+
102
+ ##
103
+ # Attachments we need to add after save.
104
+ def create_attachment(name,file)
105
+ if file.respond_to?(:read)
106
+ filename = file.respond_to?(:original_filename) ?
107
+ file.original_filename : File.basename(file.path)
108
+ type = MIME::Types.type_for(filename).first
109
+ mime = type ? type.content_type : "application/octet-stream"
110
+ send("#{name}_id=", BSON::ObjectID.new)
111
+ send("#{name}_name=", filename)
112
+ send("#{name}_size=", File.size(file))
113
+ send("#{name}_type=", mime)
114
+ create_attachment_queue[name] = file
115
+ end
116
+ end
117
+
118
+ ##
119
+ # Save an attachment to GridFS
120
+ def create_grid_attachment(name,file)
121
+ grid.put(
122
+ file.read,
123
+ :filename => attributes["#{name}_name"],
124
+ :content_type => attributes["#{name}_type"],
125
+ :_id => attributes["#{name}_id"]
126
+ )
127
+ create_attachment_queue.delete(name)
128
+ end
129
+
130
+ ##
131
+ # Attachments we need to remove after save
132
+ def delete_attachment(name,id)
133
+ delete_attachment_queue[name] = id if id.is_a?(BSON::ObjectID)
134
+ send("#{name}_id=", nil)
135
+ send("#{name}_name=", nil)
136
+ send("#{name}_size=", nil)
137
+ send("#{name}_type=", nil)
138
+ end
139
+
140
+ ##
141
+ # Delete an attachment from GridFS
142
+ def delete_grid_attachment(name,id)
143
+ grid.delete(id) if id.is_a?(BSON::ObjectID)
144
+ delete_attachment_queue.delete(name)
145
+ end
146
+
147
+ ##
148
+ # Create attachments marked for creation
149
+ def create_attachments
150
+ create_attachment_queue.each {|k,v| create_grid_attachment(k,v)}
151
+ end
152
+
153
+ ##
154
+ # Delete attachments marked for deletion
155
+ def delete_attachments
156
+ delete_attachment_queue.each {|k,v| delete_grid_attachment(k,v)}
157
+ end
158
+
159
+ ##
160
+ # Deletes all attachments from document
161
+ def destroy_attachments
162
+ self.class.attachment_types.each do |name|
163
+ delete_attachment(name, send("#{name}_id"))
164
+ end
165
+ end
166
+
167
+ end
168
+ end
169
+ end
data/lib/rack/grid.rb ADDED
@@ -0,0 +1,68 @@
1
+ require 'timeout'
2
+ require 'mongo'
3
+
4
+ module Rack
5
+ class Grid
6
+ class ConnectionError < StandardError ; end
7
+
8
+ attr_reader :host, :port, :database, :prefix, :db, :username, :password
9
+
10
+ def initialize(app, options = {})
11
+ options = options.each do |k,v|
12
+ if k.is_a?(Symbol)
13
+ options[k.to_s] = v
14
+ options.delete(k)
15
+ end
16
+ end
17
+ options = {
18
+ 'host' => 'localhost',
19
+ 'prefix' => 'grid',
20
+ 'port' => Mongo::Connection::DEFAULT_PORT
21
+ }.merge(options)
22
+
23
+ @app = app
24
+ @host = options['host']
25
+ @port = options['port']
26
+ @database = options['database']
27
+ @prefix = options['prefix']
28
+ @username = options['username']
29
+ @password = options['password']
30
+ @db = nil
31
+
32
+ connect!
33
+ end
34
+
35
+ ##
36
+ # Strip the _id out of the path. This allows the user to send something
37
+ # like /grid/4ba69fde8c8f369a6e000003/filename.jpg to find the file
38
+ # with an id of 4ba69fde8c8f369a6e000003.
39
+ def call(env)
40
+ request = Rack::Request.new(env)
41
+ if request.path_info =~ /^\/#{prefix}\/(\w+).*$/
42
+ grid_request($1)
43
+ else
44
+ @app.call(env)
45
+ end
46
+ end
47
+
48
+ ##
49
+ # Get file from GridFS or return a 404
50
+ def grid_request(id)
51
+ file = Mongo::Grid.new(db).get(BSON::ObjectID.from_string(id))
52
+ [200, {'Content-Type' => file.content_type}, [file.read]]
53
+ rescue Mongo::GridError, BSON::InvalidObjectID
54
+ [404, {'Content-Type' => 'text/plain'}, ['File not found.']]
55
+ end
56
+
57
+ private
58
+ def connect!
59
+ Timeout::timeout(5) do
60
+ @db = Mongo::Connection.new(host,port).db(database)
61
+ db.authenticate(username, password) if (username || password)
62
+ end
63
+ rescue StandardError => e
64
+ raise ConnectionError, "Timeout connecting to GridFS (#{e.to_s})"
65
+ end
66
+
67
+ end
68
+ end
File without changes
File without changes
metadata ADDED
@@ -0,0 +1,102 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: mongoid_grid
3
+ version: !ruby/object:Gem::Version
4
+ hash: 23
5
+ prerelease: false
6
+ segments:
7
+ - 0
8
+ - 0
9
+ - 4
10
+ version: 0.0.4
11
+ platform: ruby
12
+ authors:
13
+ - Dusty Doris
14
+ autorequire:
15
+ bindir: bin
16
+ cert_chain: []
17
+
18
+ date: 2010-08-11 00:00:00 -04:00
19
+ default_executable:
20
+ dependencies:
21
+ - !ruby/object:Gem::Dependency
22
+ name: mime-types
23
+ prerelease: false
24
+ requirement: &id001 !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ">="
28
+ - !ruby/object:Gem::Version
29
+ hash: 3
30
+ segments:
31
+ - 0
32
+ version: "0"
33
+ type: :runtime
34
+ version_requirements: *id001
35
+ - !ruby/object:Gem::Dependency
36
+ name: mongoid
37
+ prerelease: false
38
+ requirement: &id002 !ruby/object:Gem::Requirement
39
+ none: false
40
+ requirements:
41
+ - - ">="
42
+ - !ruby/object:Gem::Version
43
+ hash: 4067859275
44
+ segments:
45
+ - 2
46
+ - 0
47
+ - 0
48
+ - beta
49
+ - 16
50
+ version: 2.0.0.beta.16
51
+ type: :runtime
52
+ version_requirements: *id002
53
+ description: Plugin for Mongoid to use GridFS and a Rack helper
54
+ email: github@dusty.name
55
+ executables: []
56
+
57
+ extensions: []
58
+
59
+ extra_rdoc_files:
60
+ - README.txt
61
+ files:
62
+ - README.txt
63
+ - lib/mongoid/grid.rb
64
+ - lib/rack/grid.rb
65
+ - test/test_mongoid_grid.rb
66
+ - test/test_rack_grid.rb
67
+ has_rdoc: true
68
+ homepage: http://github.com/dusty/mongoid_grid
69
+ licenses: []
70
+
71
+ post_install_message:
72
+ rdoc_options: []
73
+
74
+ require_paths:
75
+ - lib
76
+ required_ruby_version: !ruby/object:Gem::Requirement
77
+ none: false
78
+ requirements:
79
+ - - ">="
80
+ - !ruby/object:Gem::Version
81
+ hash: 3
82
+ segments:
83
+ - 0
84
+ version: "0"
85
+ required_rubygems_version: !ruby/object:Gem::Requirement
86
+ none: false
87
+ requirements:
88
+ - - ">="
89
+ - !ruby/object:Gem::Version
90
+ hash: 3
91
+ segments:
92
+ - 0
93
+ version: "0"
94
+ requirements: []
95
+
96
+ rubyforge_project: none
97
+ rubygems_version: 1.3.7
98
+ signing_key:
99
+ specification_version: 3
100
+ summary: Plugin for Mongoid to use GridFS and a Rack helper
101
+ test_files: []
102
+