nifty-attachments 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.
- data/lib/nifty/attachments.rb +4 -0
- data/lib/nifty/attachments/attachment.rb +53 -0
- data/lib/nifty/attachments/middleware.rb +29 -0
- data/lib/nifty/attachments/migration.rb +16 -0
- data/lib/nifty/attachments/migration_generator.rb +21 -0
- data/lib/nifty/attachments/model_extension.rb +47 -0
- data/lib/nifty/attachments/railtie.rb +24 -0
- data/lib/nifty/attachments/version.rb +5 -0
- metadata +53 -0
@@ -0,0 +1,53 @@
|
|
1
|
+
module Nifty
|
2
|
+
module Attachments
|
3
|
+
class Attachment < ActiveRecord::Base
|
4
|
+
|
5
|
+
# Set the table name
|
6
|
+
self.table_name = 'nifty_attachments'
|
7
|
+
|
8
|
+
# This will be the ActionDispatch::UploadedFile object which be diseminated
|
9
|
+
# by the class on save.
|
10
|
+
attr_accessor :uploaded_file
|
11
|
+
|
12
|
+
# Relationships
|
13
|
+
belongs_to :parent, :polymorphic => true
|
14
|
+
|
15
|
+
# Validations
|
16
|
+
validates :file_name, :presence => true
|
17
|
+
validates :file_type, :presence => true
|
18
|
+
validates :data, :presence => true
|
19
|
+
validates :digest, :presence => true
|
20
|
+
validates :token, :presence => true, :uniqueness => true
|
21
|
+
|
22
|
+
# All attachments should have a token assigned to this
|
23
|
+
before_validation { self.token = SecureRandom.uuid if self.token.blank? }
|
24
|
+
|
25
|
+
# Copy values from the `uploaded_file` and set them as the appropriate
|
26
|
+
# fields on this model
|
27
|
+
before_validation do
|
28
|
+
if self.uploaded_file
|
29
|
+
self.data = self.uploaded_file.tempfile.read
|
30
|
+
self.file_name = self.uploaded_file.original_filename
|
31
|
+
self.file_type = self.uploaded_file.content_type
|
32
|
+
self.digest = Digest::MD5.hexdigest(self.data)
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
# Return the attachment for a given role
|
37
|
+
def self.for(role)
|
38
|
+
self.where(:role => role).first
|
39
|
+
end
|
40
|
+
|
41
|
+
# Return the path to the attachment
|
42
|
+
def path
|
43
|
+
"/attachment/#{token}/#{file_name}"
|
44
|
+
end
|
45
|
+
|
46
|
+
# Is the attachment an image?
|
47
|
+
def image?
|
48
|
+
file_type =~ /\Aimage\//
|
49
|
+
end
|
50
|
+
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
module Nifty
|
2
|
+
module Attachments
|
3
|
+
class Middleware
|
4
|
+
|
5
|
+
def initialize(app)
|
6
|
+
@app = app
|
7
|
+
end
|
8
|
+
|
9
|
+
def call(env)
|
10
|
+
if env['PATH_INFO'] =~ /\A\/attachment\/([a-f0-9\-]{36})\/(.*)/
|
11
|
+
if attachment = Nifty::Attachments::Attachment.find_by_token($1)
|
12
|
+
[200, {
|
13
|
+
'Content-Length' => attachment.data.bytesize.to_s,
|
14
|
+
'Content-Type' => attachment.file_type,
|
15
|
+
'Cache-Control' => "public, maxage=#{1.year.to_i}",
|
16
|
+
'Content-Disposition' => "attachment; filename=\"#{attachment.file_name}\""
|
17
|
+
},
|
18
|
+
[attachment.data]]
|
19
|
+
else
|
20
|
+
[404, {}, ["Attachment not found"]]
|
21
|
+
end
|
22
|
+
else
|
23
|
+
@app.call(env)
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
class CreateNiftyAttachmentsTable < ActiveRecord::Migration
|
2
|
+
|
3
|
+
def up
|
4
|
+
create_table :nifty_attachments do |t|
|
5
|
+
t.integer :parent_id
|
6
|
+
t.string :parent_type, :token, :digest, :role, :file_name, :file_type
|
7
|
+
t.binary :data, :limit => 10.megabytes
|
8
|
+
t.timestamps
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
def down
|
13
|
+
drop_table :nifty_attachments
|
14
|
+
end
|
15
|
+
|
16
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
require 'rails/generators'
|
2
|
+
require 'rails/generators/migration'
|
3
|
+
|
4
|
+
module Nifty
|
5
|
+
module Attachments
|
6
|
+
class MigrationGenerator < Rails::Generators::Base
|
7
|
+
include Rails::Generators::Migration
|
8
|
+
|
9
|
+
source_root File.expand_path("../", __FILE__)
|
10
|
+
|
11
|
+
def self.next_migration_number(path)
|
12
|
+
Time.now.utc.strftime("%Y%m%d%H%M%S")
|
13
|
+
end
|
14
|
+
|
15
|
+
def create_model_file
|
16
|
+
migration_template 'migration.rb', "db/migrate/create_nifty_attachments_table"
|
17
|
+
end
|
18
|
+
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,47 @@
|
|
1
|
+
module Nifty
|
2
|
+
module Attachments
|
3
|
+
module ModelExtension
|
4
|
+
|
5
|
+
def self.included(base)
|
6
|
+
base.extend ClassMethods
|
7
|
+
base.before_save do
|
8
|
+
if @pending_attachments
|
9
|
+
@pending_attachments.each do |pa|
|
10
|
+
old_attachments = self.nifty_attachments.where(:role => pa[:role]).pluck(:id)
|
11
|
+
self.nifty_attachments.create(:uploaded_file => pa[:file], :role => pa[:role])
|
12
|
+
self.nifty_attachments.where(:id => old_attachments).destroy_all
|
13
|
+
end
|
14
|
+
@pending_attachments = nil
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
module ClassMethods
|
20
|
+
|
21
|
+
def attachment(name)
|
22
|
+
unless self.reflect_on_all_associations(:has_many).map(&:name).include?(:nifty_attachments)
|
23
|
+
has_many :nifty_attachments, :as => :parent, :dependent => :destroy, :class_name => 'Nifty::Attachments::Attachment'
|
24
|
+
end
|
25
|
+
|
26
|
+
has_one name, -> { select(:id, :token, :digest, :parent_id, :parent_type, :file_name, :file_type).where(:role => name) }, :class_name => 'Nifty::Attachments::Attachment', :as => :parent
|
27
|
+
|
28
|
+
define_method "#{name}_file" do
|
29
|
+
instance_variable_get("@#{name}_file")
|
30
|
+
end
|
31
|
+
|
32
|
+
define_method "#{name}_file=" do |file|
|
33
|
+
instance_variable_set("@#{name}_file", file)
|
34
|
+
if file.is_a?(ActionDispatch::Http::UploadedFile)
|
35
|
+
@pending_attachments ||= []
|
36
|
+
@pending_attachments << {:role => name, :file => file}
|
37
|
+
else
|
38
|
+
nil
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
end
|
44
|
+
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
module Nifty
|
2
|
+
module Attachments
|
3
|
+
class Railtie < Rails::Railtie #:nodoc:
|
4
|
+
|
5
|
+
initializer 'nifty.attachments.initialize' do |app|
|
6
|
+
|
7
|
+
require 'nifty/attachments/middleware'
|
8
|
+
app.config.middleware.use Nifty::Attachments::Middleware
|
9
|
+
|
10
|
+
ActiveSupport.on_load(:active_record) do
|
11
|
+
require 'nifty/attachments/attachment'
|
12
|
+
require 'nifty/attachments/model_extension'
|
13
|
+
::ActiveRecord::Base.send :include, Nifty::Attachments::ModelExtension
|
14
|
+
end
|
15
|
+
|
16
|
+
end
|
17
|
+
|
18
|
+
generators do
|
19
|
+
require 'nifty/attachments/migration_generator'
|
20
|
+
end
|
21
|
+
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
metadata
ADDED
@@ -0,0 +1,53 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: nifty-attachments
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 1.0.0
|
5
|
+
prerelease:
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Adam Cooke
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2013-10-07 00:00:00.000000000 Z
|
13
|
+
dependencies: []
|
14
|
+
description: Attach documents & files to Active Record models
|
15
|
+
email:
|
16
|
+
- adam@niftyware.io
|
17
|
+
executables: []
|
18
|
+
extensions: []
|
19
|
+
extra_rdoc_files: []
|
20
|
+
files:
|
21
|
+
- lib/nifty/attachments/attachment.rb
|
22
|
+
- lib/nifty/attachments/middleware.rb
|
23
|
+
- lib/nifty/attachments/migration.rb
|
24
|
+
- lib/nifty/attachments/migration_generator.rb
|
25
|
+
- lib/nifty/attachments/model_extension.rb
|
26
|
+
- lib/nifty/attachments/railtie.rb
|
27
|
+
- lib/nifty/attachments/version.rb
|
28
|
+
- lib/nifty/attachments.rb
|
29
|
+
homepage: https://github.com/niftyware/attachments
|
30
|
+
licenses: []
|
31
|
+
post_install_message:
|
32
|
+
rdoc_options: []
|
33
|
+
require_paths:
|
34
|
+
- lib
|
35
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
36
|
+
none: false
|
37
|
+
requirements:
|
38
|
+
- - ! '>='
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '0'
|
41
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
42
|
+
none: false
|
43
|
+
requirements:
|
44
|
+
- - ! '>='
|
45
|
+
- !ruby/object:Gem::Version
|
46
|
+
version: '0'
|
47
|
+
requirements: []
|
48
|
+
rubyforge_project:
|
49
|
+
rubygems_version: 1.8.23
|
50
|
+
signing_key:
|
51
|
+
specification_version: 3
|
52
|
+
summary: Attach documents & files to Active Record models
|
53
|
+
test_files: []
|