mongoid_grid 0.0.4 → 0.0.5

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.
Files changed (3) hide show
  1. data/lib/mongoid/grid.rb +21 -22
  2. data/lib/rack/grid.rb +62 -15
  3. metadata +7 -7
data/lib/mongoid/grid.rb CHANGED
@@ -2,14 +2,14 @@ require 'mime/types'
2
2
  require 'mongoid'
3
3
  module Mongoid
4
4
  module Grid
5
-
5
+
6
6
  def self.included(base)
7
7
  base.send(:extend, ClassMethods)
8
8
  base.send(:include, InstanceMethods)
9
9
  end
10
-
10
+
11
11
  module ClassMethods
12
-
12
+
13
13
  ##
14
14
  # Declare an attachment for the object
15
15
  #
@@ -52,7 +52,7 @@ module Mongoid
52
52
  send(:delete_attachment, name, send("#{name}_id"))
53
53
  end
54
54
  end
55
-
55
+
56
56
  ##
57
57
  # Return the relative URL to the file for use with Rack::Grid
58
58
  # eg: /grid/4ba69fde8c8f369a6e000003/somefile.png
@@ -63,50 +63,50 @@ module Mongoid
63
63
  end
64
64
 
65
65
  end
66
-
66
+
67
67
  ##
68
- # Accessor to GridFS
68
+ # Accessor to GridFS
69
69
  def grid
70
70
  @grid ||= Mongo::Grid.new(Mongoid.database)
71
71
  end
72
-
72
+
73
73
  ##
74
74
  # All the attachments types for this class
75
75
  def attachment_types
76
76
  @attachment_types ||= []
77
77
  end
78
-
78
+
79
79
  end
80
80
 
81
81
  module InstanceMethods
82
-
82
+
83
83
  private
84
84
  ##
85
85
  # Accessor to GridFS
86
86
  def grid
87
87
  @grid ||= self.class.grid
88
88
  end
89
-
89
+
90
90
  ##
91
91
  # Holds queue of attachments to create
92
92
  def create_attachment_queue
93
93
  @create_attachment_queue ||= {}
94
94
  end
95
-
95
+
96
96
  ##
97
97
  # Holds queue of attachments to delete
98
98
  def delete_attachment_queue
99
99
  @delete_attachment_queue ||= {}
100
100
  end
101
-
101
+
102
102
  ##
103
103
  # Attachments we need to add after save.
104
104
  def create_attachment(name,file)
105
105
  if file.respond_to?(:read)
106
- filename = file.respond_to?(:original_filename) ?
106
+ filename = file.respond_to?(:original_filename) ?
107
107
  file.original_filename : File.basename(file.path)
108
108
  type = MIME::Types.type_for(filename).first
109
- mime = type ? type.content_type : "application/octet-stream"
109
+ mime = type ? type.content_type : "application/octet-stream"
110
110
  send("#{name}_id=", BSON::ObjectID.new)
111
111
  send("#{name}_name=", filename)
112
112
  send("#{name}_size=", File.size(file))
@@ -114,19 +114,19 @@ module Mongoid
114
114
  create_attachment_queue[name] = file
115
115
  end
116
116
  end
117
-
117
+
118
118
  ##
119
119
  # Save an attachment to GridFS
120
120
  def create_grid_attachment(name,file)
121
121
  grid.put(
122
- file.read,
122
+ file.read,
123
123
  :filename => attributes["#{name}_name"],
124
124
  :content_type => attributes["#{name}_type"],
125
125
  :_id => attributes["#{name}_id"]
126
126
  )
127
127
  create_attachment_queue.delete(name)
128
128
  end
129
-
129
+
130
130
  ##
131
131
  # Attachments we need to remove after save
132
132
  def delete_attachment(name,id)
@@ -136,20 +136,20 @@ module Mongoid
136
136
  send("#{name}_size=", nil)
137
137
  send("#{name}_type=", nil)
138
138
  end
139
-
139
+
140
140
  ##
141
141
  # Delete an attachment from GridFS
142
142
  def delete_grid_attachment(name,id)
143
143
  grid.delete(id) if id.is_a?(BSON::ObjectID)
144
144
  delete_attachment_queue.delete(name)
145
145
  end
146
-
146
+
147
147
  ##
148
148
  # Create attachments marked for creation
149
149
  def create_attachments
150
150
  create_attachment_queue.each {|k,v| create_grid_attachment(k,v)}
151
151
  end
152
-
152
+
153
153
  ##
154
154
  # Delete attachments marked for deletion
155
155
  def delete_attachments
@@ -159,11 +159,10 @@ module Mongoid
159
159
  ##
160
160
  # Deletes all attachments from document
161
161
  def destroy_attachments
162
- self.class.attachment_types.each do |name|
162
+ self.class.attachment_types.each do |name|
163
163
  delete_attachment(name, send("#{name}_id"))
164
164
  end
165
165
  end
166
-
167
166
  end
168
167
  end
169
168
  end
data/lib/rack/grid.rb CHANGED
@@ -4,22 +4,18 @@ require 'mongo'
4
4
  module Rack
5
5
  class Grid
6
6
  class ConnectionError < StandardError ; end
7
-
8
- attr_reader :host, :port, :database, :prefix, :db, :username, :password
7
+
8
+ attr_reader :host, :port, :database, :prefix, :username, :password
9
9
 
10
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
11
+ opts = {}
12
+ options.each { |k,v| opts[k.to_s] = v }
17
13
  options = {
18
14
  'host' => 'localhost',
19
15
  'prefix' => 'grid',
20
16
  'port' => Mongo::Connection::DEFAULT_PORT
21
- }.merge(options)
22
-
17
+ }.merge(opts)
18
+
23
19
  @app = app
24
20
  @host = options['host']
25
21
  @port = options['port']
@@ -27,9 +23,15 @@ module Rack
27
23
  @prefix = options['prefix']
28
24
  @username = options['username']
29
25
  @password = options['password']
30
- @db = nil
26
+ @db = options['db']
27
+
28
+ @cache_control = options['cache_control']
29
+ end
31
30
 
32
- connect!
31
+ def db
32
+ @db = @db.call() if Proc === @db
33
+ connect! unless @db
34
+ @db
33
35
  end
34
36
 
35
37
  ##
@@ -37,7 +39,8 @@ module Rack
37
39
  # like /grid/4ba69fde8c8f369a6e000003/filename.jpg to find the file
38
40
  # with an id of 4ba69fde8c8f369a6e000003.
39
41
  def call(env)
40
- request = Rack::Request.new(env)
42
+ @env = env
43
+ request = Rack::Request.new(@env)
41
44
  if request.path_info =~ /^\/#{prefix}\/(\w+).*$/
42
45
  grid_request($1)
43
46
  else
@@ -49,7 +52,18 @@ module Rack
49
52
  # Get file from GridFS or return a 404
50
53
  def grid_request(id)
51
54
  file = Mongo::Grid.new(db).get(BSON::ObjectID.from_string(id))
52
- [200, {'Content-Type' => file.content_type}, [file.read]]
55
+
56
+ etag, last_modified = file.instance_variable_get(:@md5), Time.at( file.upload_date.to_i )
57
+ headers = {
58
+ 'ETag' => "\"#{etag}\"",
59
+ 'Last-Modified' => last_modified.httpdate,
60
+ 'Cache-Control' => cache_control_header,
61
+ }
62
+ if not_modified?( etag, last_modified )
63
+ [304, headers, 'Not Modified']
64
+ else
65
+ [200, headers.update('Content-Type' => file.content_type), [file.read]]
66
+ end
53
67
  rescue Mongo::GridError, BSON::InvalidObjectID
54
68
  [404, {'Content-Type' => 'text/plain'}, ['File not found.']]
55
69
  end
@@ -63,6 +77,39 @@ module Rack
63
77
  rescue StandardError => e
64
78
  raise ConnectionError, "Timeout connecting to GridFS (#{e.to_s})"
65
79
  end
66
-
80
+
81
+ DEFAULT_CACHE_CONTROL = "max-age=0, private, must-revalidate"
82
+ def cache_control_header
83
+ if @cache_control.blank?
84
+ DEFAULT_CACHE_CONTROL
85
+
86
+ elsif @cache_control[:no_cache]
87
+ 'no-cache'
88
+
89
+ else
90
+ extras = @cache_control[:extras]
91
+ max_age = @cache_control[:max_age]
92
+
93
+ options = []
94
+ options << "max-age=#{max_age.to_i}" if max_age
95
+ options << (@cache_control[:public] ? 'public' : 'private')
96
+ options << 'must-revalidate' if @cache_control[:must_revalidate]
97
+ options.concat(extras) if extras
98
+
99
+ options.join(', ')
100
+ end
101
+ end
102
+
103
+ def not_modified?( etag, last_modified )
104
+ if_none_match = @env['HTTP_IF_NONE_MATCH']
105
+ if if_modified_since = @env['HTTP_IF_MODIFIED_SINCE']
106
+ if_modified_since = Time.rfc2822( if_modified_since ) rescue nil
107
+ end
108
+
109
+ not_modified = if_none_match.present? || if_modified_since.present?
110
+ not_modified &&= (if_none_match == "\"#{etag}\"") if if_none_match && etag
111
+ not_modified &&= (if_modified_since >= last_modified) if if_modified_since && last_modified
112
+ not_modified
113
+ end
67
114
  end
68
115
  end
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: mongoid_grid
3
3
  version: !ruby/object:Gem::Version
4
- hash: 23
4
+ hash: 21
5
5
  prerelease: false
6
6
  segments:
7
7
  - 0
8
8
  - 0
9
- - 4
10
- version: 0.0.4
9
+ - 5
10
+ version: 0.0.5
11
11
  platform: ruby
12
12
  authors:
13
13
  - Dusty Doris
@@ -15,7 +15,7 @@ autorequire:
15
15
  bindir: bin
16
16
  cert_chain: []
17
17
 
18
- date: 2010-08-11 00:00:00 -04:00
18
+ date: 2010-09-13 00:00:00 -04:00
19
19
  default_executable:
20
20
  dependencies:
21
21
  - !ruby/object:Gem::Dependency
@@ -40,14 +40,14 @@ dependencies:
40
40
  requirements:
41
41
  - - ">="
42
42
  - !ruby/object:Gem::Version
43
- hash: 4067859275
43
+ hash: 62196417
44
44
  segments:
45
45
  - 2
46
46
  - 0
47
47
  - 0
48
48
  - beta
49
- - 16
50
- version: 2.0.0.beta.16
49
+ - 17
50
+ version: 2.0.0.beta.17
51
51
  type: :runtime
52
52
  version_requirements: *id002
53
53
  description: Plugin for Mongoid to use GridFS and a Rack helper