nifty-attachments 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,4 @@
1
+ require 'securerandom'
2
+ require 'digest/md5'
3
+ require 'nifty/attachments/version'
4
+ require 'nifty/attachments/railtie' if defined?(Rails)
@@ -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
@@ -0,0 +1,5 @@
1
+ module Nifty
2
+ module Attachments
3
+ VERSION = '1.0.0'
4
+ end
5
+ 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: []