paperclip_database_storage 3.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/MIT_LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2010 [Martin Caruso]
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,59 @@
1
+ paperclip_database_storage
2
+ ==================
3
+
4
+ Adds support for storing a paperclip attachment file contents in a database table.
5
+
6
+ Requirements
7
+ ------------
8
+
9
+ paperclip_database_storage requires [Paperclip](https://github.com/thoughtbot/paperclip) version **>= 3.2.0**.
10
+
11
+ Installation
12
+ ------------
13
+
14
+ paperclip_database_storage is distributed as a gem, and that is how it should be used in your app.
15
+
16
+ Include the gem in your `Gemfile`, from rubygems:
17
+
18
+ gem 'paperclip_database_storage', '>= 3.2.0'
19
+
20
+ Or, get the master branch from the repository:
21
+
22
+ gem 'paperclip_database_storage', :git => 'git://github.com/gokuu/paperclip_database_storage.git'
23
+
24
+ Usage
25
+ -----
26
+
27
+ All you need to do is, when defining a [Paperclip](https://github.com/thoughtbot/paperclip) attachment, set its `:storage` option as `:database`:
28
+
29
+ ```ruby
30
+ class MyModel < ActiveRecord::Base
31
+ has_attached_file :attachment,
32
+ :storage => :database,
33
+ :styles => {
34
+ :medium => "300x300>",
35
+ :thumb => "100x100>"
36
+ },
37
+ :url => "/:class/:attachment/:id/:style/:basename.:extension"
38
+ end
39
+ ```
40
+
41
+ Remarks
42
+ -------
43
+
44
+ The migration defined by `paperclip_database_storage` contains several indexes, as every possible combination of the fields that can identify a single attachment. This should help getting an attachment as quickly as possible using any combination of parameters
45
+
46
+ Limitations
47
+ -----------
48
+
49
+ * Paperclip-database currently only supports one database attachment per model.
50
+ * Although you can define a custom :url option for getting the attachment, make sure you define one that uniquelly identifies each attachment, otherwise the plugin will raise an Exception.
51
+
52
+ TO-DO
53
+ -----
54
+
55
+ * Add tests!
56
+ * Add support for more than one database attachment per model
57
+ * Enable defining a separate table for each different attachment
58
+
59
+ Copyright (c) 2012 [Pedro Rodrigues], released under the MIT license
data/Rakefile ADDED
@@ -0,0 +1,23 @@
1
+ require 'rake'
2
+ require 'rake/testtask'
3
+ require 'rake/rdoctask'
4
+
5
+ desc 'Default: run unit tests.'
6
+ task :default => :test
7
+
8
+ desc 'Test the paperclip_database gem'
9
+ Rake::TestTask.new(:test) do |t|
10
+ t.libs << 'lib'
11
+ t.libs << 'test'
12
+ t.pattern = 'test/**/*_test.rb'
13
+ t.verbose = true
14
+ end
15
+
16
+ desc 'Generate documentation for the paperclip_database gem'
17
+ Rake::RDocTask.new(:rdoc) do |rdoc|
18
+ rdoc.rdoc_dir = 'rdoc'
19
+ rdoc.title = 'Paperclipdb'
20
+ rdoc.options << '--line-numbers' << '--inline-source'
21
+ rdoc.rdoc_files.include('README')
22
+ rdoc.rdoc_files.include('lib/**/*.rb')
23
+ end
@@ -0,0 +1,19 @@
1
+ class PaperclipDatabaseStorage::AttachmentsController < ApplicationController
2
+ def get_attachment
3
+ conditions = {}
4
+ conditions[:attached_type] = params[:class].singularize.camelize if params[:class]
5
+ conditions[:attached_id] = params[:id] if params[:id]
6
+ conditions[:attached_id] ||= params[:id_partition].gsub(/\//, '').to_i if params[:id_partition]
7
+ conditions[:attachment_name] = params[:attachment].singularize if params[:attachment]
8
+ conditions[:style] = params[:style] if params[:style]
9
+
10
+
11
+ attachments = PaperclipDatabaseStorage::Attachment.where(conditions)
12
+
13
+ raise ActionController::RoutingError.new('Image not Found') if attachments.empty?
14
+ raise ActionController::RoutingError.new('Too many images found. Check your route definition') if attachments.length > 1
15
+
16
+ attachment = attachments.first
17
+ send_data attachment.file_data, :type => attachment.content_type
18
+ end
19
+ end
@@ -0,0 +1,11 @@
1
+ module PaperclipDatabaseStorage
2
+ class Attachment < ActiveRecord::Base
3
+ belongs_to :attached, :polymorphic => true
4
+
5
+ attr_accessible :style, :file_data, :content_type, :file_size, :attachment_name
6
+
7
+ def self.table_name
8
+ return 'paperclip_database_storage_attachments'
9
+ end
10
+ end
11
+ end
data/config/routes.rb ADDED
@@ -0,0 +1,26 @@
1
+ Rails.application.routes.draw do
2
+ # Dynamically create routes based on defined attachments
3
+ Rails.application.eager_load!
4
+
5
+ loaded_url_templates = []
6
+ must_create_default_route = false
7
+
8
+ Paperclip.classes_with_attachments.each do |class_name|
9
+ klass = class_name.constantize
10
+
11
+ klass.attachment_definitions.each do |attachment_name, definition|
12
+ must_create_default_route = true and next unless definition.has_key?(:url)
13
+ next if loaded_url_templates.include?(definition[:url])
14
+
15
+ loaded_url_templates << definition[:url]
16
+
17
+ #ap [klass.name, attachment_name, definition]
18
+ get definition[:url] => 'paperclip_database_storage/attachments#get_attachment'
19
+ end
20
+ end
21
+
22
+ # Generate the default route, if necessary
23
+ if must_create_default_route
24
+ get Paperclip::Attachment.default_options[:url].gsub(/:id_partition/, '*id_partition') => 'paperclip_database_storage/attachments#get_attachment', :as => :default_pds
25
+ end
26
+ end
@@ -0,0 +1,31 @@
1
+ class CreatePaperclipDatabaseStorageAttachments < ActiveRecord::Migration
2
+ def self.up
3
+ create_table :paperclip_database_storage_attachments do |t|
4
+ t.string :attached_type, :null => false
5
+ t.integer :attached_id, :null => false
6
+ t.string :attachment_name, :null => false
7
+ t.string :style, :null => false
8
+ t.binary :file_data, :null => false
9
+ t.string :content_type
10
+ t.integer :file_size
11
+ t.timestamps
12
+ end
13
+ add_index :paperclip_database_storage_attachments, [ :attached_type, :attached_id, :attachment_name, :style ], :unique => true, :name => :idx_attachments_1
14
+ add_index :paperclip_database_storage_attachments, [ :attached_type, :attached_id, :attachment_name ], :name => :idx_attachments_2
15
+ add_index :paperclip_database_storage_attachments, [ :attached_type, :attached_id ], :name => :idx_attachments_3
16
+ add_index :paperclip_database_storage_attachments, [ :attached_type ], :name => :idx_attachments_4
17
+ add_index :paperclip_database_storage_attachments, [ :attached_type, :attached_id, :style ], :name => :idx_attachments_5
18
+ add_index :paperclip_database_storage_attachments, [ :attached_type, :style ], :name => :idx_attachments_6
19
+ add_index :paperclip_database_storage_attachments, [ :style ], :name => :idx_attachments_7
20
+ add_index :paperclip_database_storage_attachments, [ :attached_type, :attachment_name, :style ], :name => :idx_attachments_8
21
+ add_index :paperclip_database_storage_attachments, [ :attachment_name, :style ], :name => :idx_attachments_9
22
+ add_index :paperclip_database_storage_attachments, [ :attachment_name ], :name => :idx_attachments_10
23
+ add_index :paperclip_database_storage_attachments, [ :attached_type, :attachment_name, :style ], :name => :idx_attachments_11
24
+ add_index :paperclip_database_storage_attachments, [ :attachment_name, :style ], :name => :idx_attachments_12
25
+ add_index :paperclip_database_storage_attachments, [ :style ], :name => :idx_attachments_13
26
+ end
27
+
28
+ def self.down
29
+ drop_table :paperclip_database_storage_attachments
30
+ end
31
+ end
@@ -0,0 +1,11 @@
1
+ #require 'paperclip_database/storage.rb'
2
+ require 'paperclip_database_storage'
3
+ require 'paperclip_database_storage/storage/database'
4
+ require 'rails'
5
+ require 'paperclip'
6
+
7
+ # This will load the necessary models and controllers
8
+ module PaperclipDatabaseStorage
9
+ class Engine < Rails::Engine
10
+ end
11
+ end
@@ -0,0 +1,87 @@
1
+ module Paperclip
2
+ module Storage
3
+ module Database
4
+ def self.extended(base)
5
+ base.instance_eval do
6
+ override_default_options base
7
+ end
8
+ end
9
+
10
+ def override_default_options(base)
11
+ @path = @url
12
+ end
13
+
14
+ private :override_default_options
15
+
16
+ def exists?(style = default_style)
17
+ return !get_attachment(style).nil?
18
+ end
19
+
20
+ def path(style = default_style)
21
+ return style
22
+ end
23
+
24
+ def get_attachment(style)
25
+ return PaperclipDatabaseStorage::Attachment.find(:first, :conditions => {
26
+ :style => style,
27
+ :attached_type => self.instance.class.name,
28
+ :attached_id => self.instance.id,
29
+ :attachment_name => self.get_attachment_definitions.keys.first
30
+ })
31
+ end
32
+
33
+ def get_attachment_definitions
34
+ attachment_definitions = self.instance.class.attachment_definitions
35
+
36
+ if attachment_definitions.select { |k,v| v[:storage] == :database }.count > 1
37
+ raise Exception.new('paperclip-database does not support more than one attachment per model')
38
+ end
39
+
40
+ return attachment_definitions
41
+ end
42
+
43
+
44
+ def to_file style = default_style
45
+ if @queued_for_write[style]
46
+ @queued_for_write[style]
47
+ elsif exists?(style)
48
+ attachment = get_attachment(style)
49
+ tempfile = Tempfile.new attachment.base_name
50
+ tempfile.write attachment.file_data
51
+ tempfile
52
+ else
53
+ nil
54
+ end
55
+ end
56
+
57
+ def flush_writes
58
+ puts("[paperclip] Writing files #{@queued_for_write.count}")
59
+ attachment_definitions = get_attachment_definitions
60
+
61
+ @queued_for_write.each do |style, file|
62
+ puts("[paperclip] Writing files for #{file} #{style}")
63
+
64
+ PaperclipDatabaseStorage::Attachment.new do |a|
65
+ a.attached_type = self.instance.class.name
66
+ a.attached_id = self.instance.id
67
+ a.style = style
68
+ a.content_type = self.instance_variable_get("@_#{self.name.to_s}_content_type")
69
+ a.attachment_name = attachment_definitions.keys.first
70
+ a.file_size = file.size
71
+ a.file_data = file.read
72
+ end.save
73
+ end
74
+ @queued_for_write = {}
75
+ end
76
+
77
+ def flush_deletes
78
+ @queued_for_delete.each do |style|
79
+ puts("[paperclip] Deleting files for #{style}")
80
+ attachment = get_attachment(style)
81
+ attachment.destroy if !attachment.nil?
82
+ end
83
+ @queued_for_delete = []
84
+ end
85
+ end
86
+ end
87
+ end
@@ -0,0 +1,3 @@
1
+ module PaperclipDatabaseStorage
2
+ VERSION = "3.0.0" unless defined? PaperclipDatabaseStorage::VERSION
3
+ end
@@ -0,0 +1,21 @@
1
+ namespace :'paperclip_database_storage' do
2
+ desc 'Copy necessary migrations from paperclip_database_storage to the rails project'
3
+ task :setup => :environment do
4
+ plugin_root = File.dirname(File.dirname(File.dirname(__FILE__)))
5
+
6
+ Dir[File.join(plugin_root, 'db', 'migrate', '*.rb')].each do |file|
7
+ # First, check if the migration has already been copied
8
+ if Dir[File.join('db', 'migrate', "*#{File.basename(file)}*")].any?
9
+ puts "Migration #{File.basename(file)} has already been copied, skipping..."
10
+ else
11
+ dest_file = "#{Time.now.strftime('%Y%m%d%H%M%S')}_#{File.basename(file)}"
12
+ dest_dir = File.join(Rails.root, 'db', 'migrate')
13
+
14
+ puts "Copying #{File.basename(file)} to #{dest_file}"
15
+
16
+ FileUtils.mkdir_p dest_dir
17
+ FileUtils.cp(file, File.join(dest_dir, dest_file))
18
+ end
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,22 @@
1
+ $LOAD_PATH.push File.expand_path("../lib", __FILE__)
2
+ require 'paperclip_database_storage/version'
3
+
4
+ Gem::Specification.new do |s|
5
+ s.name = 'paperclip_database_storage'
6
+ s.version = PaperclipDatabaseStorage::VERSION
7
+
8
+ s.authors = ['Pedro Rodrigues']
9
+ s.date = '2012-10-01'
10
+ s.summary = 'Database storage support for paperclip file attachment plugin'
11
+ s.description = 'Adds support for storing the contents of files attachment via paperclip plugin on the database'
12
+ s.email = 'pedro@bbde.org'
13
+ s.files = `git ls-files`.split("\n")
14
+ s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
15
+ s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
16
+ s.require_paths = ['lib']
17
+ s.required_ruby_version = ">= 1.9.2"
18
+
19
+ s.homepage = 'http://github.com/gokuu/paperclip_database_storage'
20
+
21
+ s.add_dependency 'paperclip', [">= 3.0.0"]
22
+ end
metadata ADDED
@@ -0,0 +1,73 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: paperclip_database_storage
3
+ version: !ruby/object:Gem::Version
4
+ version: 3.0.0
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Pedro Rodrigues
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2012-10-01 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: paperclip
16
+ requirement: !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ! '>='
20
+ - !ruby/object:Gem::Version
21
+ version: 3.0.0
22
+ type: :runtime
23
+ prerelease: false
24
+ version_requirements: !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ! '>='
28
+ - !ruby/object:Gem::Version
29
+ version: 3.0.0
30
+ description: Adds support for storing the contents of files attachment via paperclip
31
+ plugin on the database
32
+ email: pedro@bbde.org
33
+ executables: []
34
+ extensions: []
35
+ extra_rdoc_files: []
36
+ files:
37
+ - MIT_LICENSE
38
+ - README.md
39
+ - Rakefile
40
+ - app/controllers/paperclip_database_storage/attachments_controller.rb
41
+ - app/models/paperclip_database_storage/attachment.rb
42
+ - config/routes.rb
43
+ - db/migrate/create_paperclip_database_storage_attachments.rb
44
+ - lib/paperclip_database_storage.rb
45
+ - lib/paperclip_database_storage/storage/database.rb
46
+ - lib/paperclip_database_storage/version.rb
47
+ - lib/tasks/paperclip_database_storage.rake
48
+ - paperclip_database_storage.gemspec
49
+ homepage: http://github.com/gokuu/paperclip_database_storage
50
+ licenses: []
51
+ post_install_message:
52
+ rdoc_options: []
53
+ require_paths:
54
+ - lib
55
+ required_ruby_version: !ruby/object:Gem::Requirement
56
+ none: false
57
+ requirements:
58
+ - - ! '>='
59
+ - !ruby/object:Gem::Version
60
+ version: 1.9.2
61
+ required_rubygems_version: !ruby/object:Gem::Requirement
62
+ none: false
63
+ requirements:
64
+ - - ! '>='
65
+ - !ruby/object:Gem::Version
66
+ version: '0'
67
+ requirements: []
68
+ rubyforge_project:
69
+ rubygems_version: 1.8.24
70
+ signing_key:
71
+ specification_version: 3
72
+ summary: Database storage support for paperclip file attachment plugin
73
+ test_files: []