mongoid_grid 0.0.4 → 0.0.5

Sign up to get free protection for your applications and to get access to all the features.
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