paperclip_i18n 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +5 -0
- data/Gemfile +4 -0
- data/README.md +3 -0
- data/Rakefile +2 -0
- data/lib/paperclip_i18n/acts_as_attachment.rb +64 -0
- data/lib/paperclip_i18n/generators/paperclip_i18n/USAGE +18 -0
- data/lib/paperclip_i18n/generators/paperclip_i18n/paperclip_i18n_generator.rb +19 -0
- data/lib/paperclip_i18n/generators/paperclip_i18n/templates/asset.rb +3 -0
- data/lib/paperclip_i18n/generators/paperclip_i18n/templates/assets_controller.rb +7 -0
- data/lib/paperclip_i18n/generators/paperclip_i18n/templates/migration.rb +21 -0
- data/lib/paperclip_i18n/has_many_attached_files.rb +81 -0
- data/lib/paperclip_i18n/upload_file_validator.rb +28 -0
- data/lib/paperclip_i18n/version.rb +3 -0
- data/lib/paperclip_i18n.rb +6 -0
- data/paperclip_i18n.gemspec +23 -0
- metadata +99 -0
data/Gemfile
ADDED
data/README.md
ADDED
data/Rakefile
ADDED
@@ -0,0 +1,64 @@
|
|
1
|
+
module PaperclipI18n
|
2
|
+
module ActsAsAttachment
|
3
|
+
def self.included(base)
|
4
|
+
base.extend(ClassMethods)
|
5
|
+
end
|
6
|
+
|
7
|
+
module ClassMethods
|
8
|
+
# Extends the model to afford the ability to associate other records with the receiving record.
|
9
|
+
#
|
10
|
+
# This module needs the paperclip plugin to work
|
11
|
+
# http://www.thoughtbot.com/projects/paperclip
|
12
|
+
def acts_as_attachment(options = {})
|
13
|
+
default_options = { :url => "/uploads/#{Rails.env}/assets/:id_partition/:basename.:style.:extension",
|
14
|
+
:path => "#{Rails.root}/public/uploads/#{Rails.env}/assets/:id_partition/:basename.:style.:extension" }.merge(options)
|
15
|
+
|
16
|
+
has_attached_file(:upload, default_options)
|
17
|
+
belongs_to(:attachable, :polymorphic => true)
|
18
|
+
scope(:i18ns, lambda { where(:upload_language => ::I18n.locale) })
|
19
|
+
include(::PaperclipI18n::ActsAsAttachment::InstanceMethods)
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
module InstanceMethods
|
24
|
+
def url(*args)
|
25
|
+
upload.url(*args)
|
26
|
+
end
|
27
|
+
|
28
|
+
def name
|
29
|
+
upload_file_name
|
30
|
+
end
|
31
|
+
|
32
|
+
def content_type
|
33
|
+
upload_content_type
|
34
|
+
end
|
35
|
+
|
36
|
+
def size
|
37
|
+
upload_file_size
|
38
|
+
end
|
39
|
+
|
40
|
+
def browser_safe?
|
41
|
+
%w(jpg gif png).include?(url.split('.').last.sub(/\?.+/, '').downcase)
|
42
|
+
end
|
43
|
+
alias_method(:web_safe?, :browser_safe?)
|
44
|
+
|
45
|
+
# This method assumes you have images that corespond to the filetypes.
|
46
|
+
# For example "image/png" becomes "image-png.png"
|
47
|
+
def icon
|
48
|
+
"#{upload_content_type.gsub(/[\/\.]/,'-')}.png"
|
49
|
+
end
|
50
|
+
|
51
|
+
def detach(attached)
|
52
|
+
a = attachings.find(:first, :conditions => ['attachable_id = ? AND attachable_type = ?', attached, attached.class.to_s])
|
53
|
+
raise(::ActiveRecord::RecordNotFound) unless a
|
54
|
+
a.destroy
|
55
|
+
end
|
56
|
+
|
57
|
+
# Rails doc says: Using polymorphic assocs with STI can be a little tricky
|
58
|
+
# --> read more @ http://api.rubyonrails.org/classes/ActiveRecord/Associations/ClassMethods.html
|
59
|
+
def attachable_type=(sType)
|
60
|
+
super(sType.to_s.classify.constantize.base_class.to_s)
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
Description:
|
2
|
+
This generator creates the migrations needed to use paperclip_i18n
|
3
|
+
|
4
|
+
Requirements:
|
5
|
+
paperclip
|
6
|
+
authlogic (http://agilewebdevelopment.com/plugins/authgasm, with a working "UserSession" Model)
|
7
|
+
UserSession.current_lang: must return the current language identifier string
|
8
|
+
|
9
|
+
Important:
|
10
|
+
Add "resources :assets, :only=>[:show]" to your routes.rb file and modify according to your needs.
|
11
|
+
|
12
|
+
Example:
|
13
|
+
rails g paperclip_i18n
|
14
|
+
|
15
|
+
This will create:
|
16
|
+
- A migration, which adds an assets and attachings table.
|
17
|
+
- A controller (assets_controller.rb)
|
18
|
+
- A model (asset.rb)
|
@@ -0,0 +1,19 @@
|
|
1
|
+
class PaperclipI18nGenerator < Rails::Generators::Base
|
2
|
+
include(Rails::Generators::Migration)
|
3
|
+
source_root(File.expand_path('../templates', __FILE__))
|
4
|
+
|
5
|
+
# taken from: http://www.themodestrubyist.com/2010/03/16/rails-3-plugins---part-3---rake-tasks-generators-initializers-oh-my/
|
6
|
+
def self.next_migration_number(dirname)
|
7
|
+
if ::ActiveRecord::Base.timestamped_migrations
|
8
|
+
::Time.now.utc.strftime('%Y%m%d%H%M%S')
|
9
|
+
else
|
10
|
+
'%.3d' % (current_migration_number(dirname) + 1)
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
def create_paperclip_i18n_migration
|
15
|
+
migration_template('migration.rb', 'db/migrate/paperclip_i18n_tables.rb')
|
16
|
+
copy_file('assets_controller.rb', 'app/controllers/assets_controller.rb')
|
17
|
+
copy_file('asset.rb', 'app/models/asset.rb')
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
class PaperclipI18nTables < ActiveRecord::Migration
|
2
|
+
def self.up
|
3
|
+
create_table('assets') do |t|
|
4
|
+
t.string('attachable_type')
|
5
|
+
t.integer('attachable_id')
|
6
|
+
t.string('upload_file_name')
|
7
|
+
t.string('upload_content_type')
|
8
|
+
t.integer('upload_file_size')
|
9
|
+
t.string('upload_language', :limit => 6, :default => 'en')
|
10
|
+
t.datetime('created_at')
|
11
|
+
t.datetime('updated_at')
|
12
|
+
t.datetime('upload_updated_at')
|
13
|
+
end
|
14
|
+
|
15
|
+
add_index('assets', ['attachable_id', 'attachable_type'], :name => 'index_assets_on_attachable_id_and_type')
|
16
|
+
end
|
17
|
+
|
18
|
+
def self.down
|
19
|
+
drop_table(:assets)
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,81 @@
|
|
1
|
+
module PaperclipI18n
|
2
|
+
module HasManyAttachedFiles
|
3
|
+
def self.included(base)
|
4
|
+
base.extend(ClassMethods)
|
5
|
+
end
|
6
|
+
|
7
|
+
module ClassMethods
|
8
|
+
# Extends the model to afford the ability to associate other records with the receiving record.
|
9
|
+
#
|
10
|
+
# This module needs the paperclip plugin to work
|
11
|
+
# http://www.thoughtbot.com/projects/paperclip
|
12
|
+
def has_many_attached_files(options = {})
|
13
|
+
write_inheritable_attribute(:has_many_attached_files_options, { :counter_cache => options[:counter_cache], :styles => options[:styles] })
|
14
|
+
class_inheritable_reader(:has_many_attached_files_options)
|
15
|
+
|
16
|
+
attr_accessor(:upload)
|
17
|
+
attr_accessor(:current_file_language)
|
18
|
+
after_save(:save_attached_files)
|
19
|
+
has_many(:assets, :as => :attachable, :dependent => :destroy)
|
20
|
+
include(::PaperclipI18n::HasManyAttachedFiles::InstanceMethods)
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
module InstanceMethods
|
25
|
+
def save_attached_files
|
26
|
+
::Asset.transaction do
|
27
|
+
if upload.is_a?(Array)
|
28
|
+
upload.each do |data_item|
|
29
|
+
create_or_update_asset(data_item) unless data_item.nil? || data_item.blank?
|
30
|
+
end
|
31
|
+
else
|
32
|
+
create_or_update_asset(upload)
|
33
|
+
end
|
34
|
+
end unless upload.nil? || upload.blank?
|
35
|
+
end
|
36
|
+
|
37
|
+
def create_or_update_asset(data_item)
|
38
|
+
override_default_styles, normalised_styles = override_default_styles?(data_item.original_filename)
|
39
|
+
asset = assets.where(:upload_language => current_language).first || Asset.new # is there an attachment, then delete the old
|
40
|
+
asset.upload.instance_variable_set('@styles', normalised_styles) if override_default_styles
|
41
|
+
asset.upload = data_item
|
42
|
+
asset.upload_language = current_language
|
43
|
+
|
44
|
+
if asset.new_record?
|
45
|
+
asset.save
|
46
|
+
assets << asset # store the asset ...
|
47
|
+
else
|
48
|
+
asset.save
|
49
|
+
end
|
50
|
+
assets(true) # reload implicitly
|
51
|
+
end
|
52
|
+
|
53
|
+
def override_default_styles?(filename)
|
54
|
+
if !has_many_attached_files_options[:styles].nil?
|
55
|
+
normalised_styles = {}
|
56
|
+
|
57
|
+
has_many_attached_files_options[:styles].each do |name, args|
|
58
|
+
dimensions, format = [args, nil].flatten[0..1]
|
59
|
+
format = nil if format.blank?
|
60
|
+
|
61
|
+
if filename.match(/\.pdf$/) # remove crop commands if file is a PDF (this fails with Imagemagick)
|
62
|
+
args.gsub!(/#/ , '')
|
63
|
+
format = 'png'
|
64
|
+
end
|
65
|
+
|
66
|
+
normalised_styles[name] = { :processors => [:thumbnail], :geometry => dimensions, :format => format }
|
67
|
+
end
|
68
|
+
|
69
|
+
return true, normalised_styles
|
70
|
+
else
|
71
|
+
return(false)
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
# based on the Authlogic plugin (http://agilewebdevelopment.com/plugins/authgasm)
|
76
|
+
def current_language
|
77
|
+
@current_file_language || ::I18n.locale
|
78
|
+
end
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
class UploadFileValidator < ActiveModel::EachValidator
|
2
|
+
DEFAULT_OPTIONS = { :content_type => nil,
|
3
|
+
:less_then => nil,
|
4
|
+
:presence => true,
|
5
|
+
:skip_on_versioning => false }
|
6
|
+
|
7
|
+
def initialize(options)
|
8
|
+
super(options)
|
9
|
+
@options = DEFAULT_OPTIONS.merge(@options)
|
10
|
+
end
|
11
|
+
|
12
|
+
def validate_each(record, attribute, value)
|
13
|
+
return if options[:skip_on_versioning] && !record.record_timestamps # due to the versioning, which is copied through jbackend
|
14
|
+
less_then = options[:less_then]
|
15
|
+
content_type = options[:content_type]
|
16
|
+
return unless options[:presence]
|
17
|
+
record.errors[attribute] << 'must be provided' if options[:presence] and !asset_available?(record, value)
|
18
|
+
|
19
|
+
if !value.nil?
|
20
|
+
record.errors[attribute] << "must be smaller then #{less_then}" if not less_then.nil? and value.size > less_then
|
21
|
+
record.errors[attribute] << "must be of a file valid type: #{content_type}" if not content_type.nil? and not value.content_type =~ content_type
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
def asset_available?(record, value)
|
26
|
+
!record.assets.i18ns.first.nil? || !value.nil?
|
27
|
+
end
|
28
|
+
end
|
@@ -0,0 +1,6 @@
|
|
1
|
+
require('paperclip_i18n/has_many_attached_files')
|
2
|
+
require('paperclip_i18n/acts_as_attachment')
|
3
|
+
require('paperclip_i18n/upload_file_validator')
|
4
|
+
|
5
|
+
ActiveRecord::Base.send(:include, ::PaperclipI18n::ActsAsAttachment)
|
6
|
+
ActiveRecord::Base.send(:include, ::PaperclipI18n::HasManyAttachedFiles)
|
@@ -0,0 +1,23 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
$:.push(File.expand_path('../lib', __FILE__))
|
3
|
+
require('paperclip_i18n/version')
|
4
|
+
|
5
|
+
Gem::Specification.new do |s|
|
6
|
+
s.name = 'paperclip_i18n'
|
7
|
+
s.version = PaperclipI18n::VERSION
|
8
|
+
s.platform = Gem::Platform::RUBY
|
9
|
+
s.authors = ['Rene Gross', 'Philipp Ullmann']
|
10
|
+
s.email = ["rg@create.at", 'philipp.ullmann@create.at']
|
11
|
+
s.homepage = ""
|
12
|
+
s.summary = 'Adding I18n image upload support to paperclip plugin'
|
13
|
+
s.description = "This gem depends on the paperclip gem. A separate file can be uploaded for each language."
|
14
|
+
|
15
|
+
s.rubyforge_project = 'paperclip_i18n'
|
16
|
+
|
17
|
+
s.files = `git ls-files`.split("\n")
|
18
|
+
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
19
|
+
s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
20
|
+
s.require_paths = ['lib']
|
21
|
+
|
22
|
+
s.add_dependency('paperclip', ['>= 2.3.8'])
|
23
|
+
end
|
metadata
ADDED
@@ -0,0 +1,99 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: paperclip_i18n
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
hash: 29
|
5
|
+
prerelease:
|
6
|
+
segments:
|
7
|
+
- 0
|
8
|
+
- 0
|
9
|
+
- 1
|
10
|
+
version: 0.0.1
|
11
|
+
platform: ruby
|
12
|
+
authors:
|
13
|
+
- Rene Gross
|
14
|
+
- Philipp Ullmann
|
15
|
+
autorequire:
|
16
|
+
bindir: bin
|
17
|
+
cert_chain: []
|
18
|
+
|
19
|
+
date: 2011-03-08 00:00:00 +01:00
|
20
|
+
default_executable:
|
21
|
+
dependencies:
|
22
|
+
- !ruby/object:Gem::Dependency
|
23
|
+
name: paperclip
|
24
|
+
prerelease: false
|
25
|
+
requirement: &id001 !ruby/object:Gem::Requirement
|
26
|
+
none: false
|
27
|
+
requirements:
|
28
|
+
- - ">="
|
29
|
+
- !ruby/object:Gem::Version
|
30
|
+
hash: 19
|
31
|
+
segments:
|
32
|
+
- 2
|
33
|
+
- 3
|
34
|
+
- 8
|
35
|
+
version: 2.3.8
|
36
|
+
type: :runtime
|
37
|
+
version_requirements: *id001
|
38
|
+
description: This gem depends on the paperclip gem. A separate file can be uploaded for each language.
|
39
|
+
email:
|
40
|
+
- rg@create.at
|
41
|
+
- philipp.ullmann@create.at
|
42
|
+
executables: []
|
43
|
+
|
44
|
+
extensions: []
|
45
|
+
|
46
|
+
extra_rdoc_files: []
|
47
|
+
|
48
|
+
files:
|
49
|
+
- .gitignore
|
50
|
+
- Gemfile
|
51
|
+
- README.md
|
52
|
+
- Rakefile
|
53
|
+
- lib/paperclip_i18n.rb
|
54
|
+
- lib/paperclip_i18n/acts_as_attachment.rb
|
55
|
+
- lib/paperclip_i18n/generators/paperclip_i18n/USAGE
|
56
|
+
- lib/paperclip_i18n/generators/paperclip_i18n/paperclip_i18n_generator.rb
|
57
|
+
- lib/paperclip_i18n/generators/paperclip_i18n/templates/asset.rb
|
58
|
+
- lib/paperclip_i18n/generators/paperclip_i18n/templates/assets_controller.rb
|
59
|
+
- lib/paperclip_i18n/generators/paperclip_i18n/templates/migration.rb
|
60
|
+
- lib/paperclip_i18n/has_many_attached_files.rb
|
61
|
+
- lib/paperclip_i18n/upload_file_validator.rb
|
62
|
+
- lib/paperclip_i18n/version.rb
|
63
|
+
- paperclip_i18n.gemspec
|
64
|
+
has_rdoc: true
|
65
|
+
homepage: ""
|
66
|
+
licenses: []
|
67
|
+
|
68
|
+
post_install_message:
|
69
|
+
rdoc_options: []
|
70
|
+
|
71
|
+
require_paths:
|
72
|
+
- lib
|
73
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
74
|
+
none: false
|
75
|
+
requirements:
|
76
|
+
- - ">="
|
77
|
+
- !ruby/object:Gem::Version
|
78
|
+
hash: 3
|
79
|
+
segments:
|
80
|
+
- 0
|
81
|
+
version: "0"
|
82
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
83
|
+
none: false
|
84
|
+
requirements:
|
85
|
+
- - ">="
|
86
|
+
- !ruby/object:Gem::Version
|
87
|
+
hash: 3
|
88
|
+
segments:
|
89
|
+
- 0
|
90
|
+
version: "0"
|
91
|
+
requirements: []
|
92
|
+
|
93
|
+
rubyforge_project: paperclip_i18n
|
94
|
+
rubygems_version: 1.6.0
|
95
|
+
signing_key:
|
96
|
+
specification_version: 3
|
97
|
+
summary: Adding I18n image upload support to paperclip plugin
|
98
|
+
test_files: []
|
99
|
+
|