effective_assets 0.1 → 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.
- checksums.yaml +7 -0
- data/MIT-LICENSE +1 -1
- data/README.md +341 -72
- data/app/assets/javascripts/effective/snippets/effective_asset.js.coffee +53 -0
- data/app/assets/javascripts/effective_assets.js +4 -0
- data/app/assets/javascripts/effective_assets/asset_box.js.coffee +36 -0
- data/app/assets/javascripts/effective_assets/asset_box_dialog.js.coffee +49 -0
- data/app/assets/javascripts/effective_assets/asset_box_drag_and_drop.js.coffee +2 -0
- data/app/assets/javascripts/effective_assets/asset_box_filtering.js.coffee +16 -0
- data/app/assets/javascripts/effective_assets/asset_box_sorting.js.coffee +8 -0
- data/app/assets/javascripts/effective_assets/jquery_ui_sortable.js +813 -585
- data/app/assets/javascripts/effective_assets/s3_uploader.js.coffee +268 -0
- data/app/assets/javascripts/effective_assets_iframe.js.coffee +28 -0
- data/app/assets/stylesheets/active_admin/effective_assets.css.scss +57 -0
- data/app/assets/stylesheets/effective_assets/_asset_box_input.scss +54 -175
- data/app/assets/stylesheets/effective_assets/_iframe_bootstrap.scss +1714 -0
- data/app/assets/stylesheets/effective_assets/_input_bootstrap.scss +508 -0
- data/app/assets/stylesheets/effective_assets_iframe.css.scss +23 -0
- data/app/controllers/effective/assets_controller.rb +41 -0
- data/app/controllers/effective/s3_uploads_controller.rb +58 -74
- data/app/helpers/effective_assets_helper.rb +30 -14
- data/app/helpers/effective_assets_s3_helper.rb +69 -0
- data/app/models/concerns/acts_as_asset_box.rb +75 -11
- data/app/models/effective/access_denied.rb +17 -0
- data/app/models/effective/asset.rb +130 -93
- data/app/models/effective/attachment.rb +2 -7
- data/app/models/effective/delayed_job.rb +33 -78
- data/app/models/effective/snippets/effective_asset.rb +19 -0
- data/app/models/effective/user_uploads.rb +19 -0
- data/app/models/inputs/asset_box.rb +154 -0
- data/app/models/inputs/asset_box_form_input.rb +7 -0
- data/app/models/inputs/asset_box_formtastic_input.rb +9 -0
- data/app/models/inputs/asset_box_input.rb +13 -82
- data/app/models/inputs/asset_box_simple_form_input.rb +7 -0
- data/app/uploaders/effective_assets_uploader.rb +14 -2
- data/app/uploaders/{asset_uploader.rb → test_asset_uploader.rb} +1 -1
- data/app/views/active_admin/effective_assets/_edit.html.haml +3 -3
- data/app/views/active_admin/effective_assets/_new.html.haml +2 -1
- data/app/views/asset_box_input/_attachment_as_list.html.haml +17 -0
- data/app/views/asset_box_input/_attachment_as_table.html.haml +32 -0
- data/app/views/asset_box_input/_attachment_as_thumbnail.html.haml +20 -0
- data/app/views/asset_box_input/_dialog.html.haml +18 -0
- data/app/views/asset_box_input/_progress_bar_template.html.haml +8 -0
- data/app/views/asset_box_input/_uploader.html.haml +21 -115
- data/app/views/effective/assets/iframe.html.haml +17 -0
- data/app/views/effective/snippets/_effective_asset.html.haml +8 -0
- data/config/routes.rb +8 -2
- data/db/migrate/01_create_effective_assets.rb.erb +3 -0
- data/lib/effective_assets.rb +34 -3
- data/lib/effective_assets/engine.rb +11 -8
- data/lib/effective_assets/version.rb +1 -1
- data/lib/generators/templates/asset_uploader.rb +35 -0
- data/lib/generators/templates/effective_assets.rb +31 -4
- data/lib/tasks/effective_assets_tasks.rake +115 -4
- data/spec/internal/config/database.yml +3 -0
- data/spec/internal/config/initializers/effective_assets.rb +18 -0
- data/spec/internal/config/routes.rb +3 -0
- data/spec/internal/db/combustion_test.sqlite +0 -0
- data/spec/internal/db/schema.rb +52 -0
- data/spec/internal/log/test.log +793 -0
- data/spec/{dummy → internal}/public/favicon.ico +0 -0
- data/spec/internal/public/sprites.png +0 -0
- data/spec/models/asset_spec.rb +119 -35
- data/spec/spec_helper.rb +9 -3
- metadata +95 -234
- data/app/assets/images/effective_assets/s3_down_button.gif +0 -0
- data/app/assets/images/effective_assets/s3_over_button.gif +0 -0
- data/app/assets/images/effective_assets/s3_up_button.gif +0 -0
- data/app/assets/images/effective_assets/s3_upload.swf +0 -0
- data/app/assets/javascripts/effective_assets/asset_box_input.js.coffee +0 -71
- data/app/assets/javascripts/effective_assets/asset_box_uploader.js +0 -122
- data/app/assets/javascripts/effective_assets/asset_box_uploader_customization.js +0 -166
- data/app/controllers/effective/attachments_controller.rb +0 -14
- data/app/views/asset_box_input/_attachment_fields.html.haml +0 -14
- data/spec/dummy/README.rdoc +0 -261
- data/spec/dummy/Rakefile +0 -7
- data/spec/dummy/app/assets/javascripts/application.js +0 -15
- data/spec/dummy/app/assets/stylesheets/application.css +0 -13
- data/spec/dummy/app/controllers/application_controller.rb +0 -3
- data/spec/dummy/app/helpers/application_helper.rb +0 -2
- data/spec/dummy/app/views/layouts/application.html.erb +0 -14
- data/spec/dummy/config.ru +0 -4
- data/spec/dummy/config/application.rb +0 -65
- data/spec/dummy/config/boot.rb +0 -10
- data/spec/dummy/config/database.yml +0 -25
- data/spec/dummy/config/environment.rb +0 -5
- data/spec/dummy/config/environments/development.rb +0 -37
- data/spec/dummy/config/environments/production.rb +0 -67
- data/spec/dummy/config/environments/test.rb +0 -37
- data/spec/dummy/config/initializers/backtrace_silencers.rb +0 -7
- data/spec/dummy/config/initializers/inflections.rb +0 -15
- data/spec/dummy/config/initializers/mime_types.rb +0 -5
- data/spec/dummy/config/initializers/secret_token.rb +0 -7
- data/spec/dummy/config/initializers/session_store.rb +0 -8
- data/spec/dummy/config/initializers/wrap_parameters.rb +0 -14
- data/spec/dummy/config/locales/en.yml +0 -5
- data/spec/dummy/config/routes.rb +0 -58
- data/spec/dummy/db/development.sqlite3 +0 -0
- data/spec/dummy/db/schema.rb +0 -16
- data/spec/dummy/db/test.sqlite3 +0 -0
- data/spec/dummy/log/development.log +0 -71
- data/spec/dummy/log/test.log +0 -33
- data/spec/dummy/public/404.html +0 -26
- data/spec/dummy/public/422.html +0 -26
- data/spec/dummy/public/500.html +0 -25
- data/spec/dummy/script/rails +0 -6
- data/spec/dummy/spec_link +0 -3
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
@import "effective_assets/asset_box_input";
|
|
2
|
+
|
|
3
|
+
body {
|
|
4
|
+
padding: 10px;
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
.form-control.filter-attachments {
|
|
8
|
+
display: inline;
|
|
9
|
+
font-weight: normal;
|
|
10
|
+
width: auto;
|
|
11
|
+
min-width: 50%;
|
|
12
|
+
margin-left: 10px;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
.asset-box-input.dragin {
|
|
16
|
+
border: 1px solid blue;
|
|
17
|
+
border-radius: 4px;
|
|
18
|
+
border-color: #66afe9;
|
|
19
|
+
box-shadow: 0 1px 1px rgba(0, 0, 0, 0.075) inset, 0 0 8px rgba(102, 175, 233, 0.6);
|
|
20
|
+
outline: 0 none;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
@import "effective_assets/iframe_bootstrap";
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
# This is basically for the CkEditor Pictures functionality
|
|
2
|
+
|
|
3
|
+
module Effective
|
|
4
|
+
class AssetsController < ApplicationController
|
|
5
|
+
layout false
|
|
6
|
+
|
|
7
|
+
def index # This is the Modal dialog that is read by CKEDITOR
|
|
8
|
+
EffectiveAssets.authorized?(self, :index, Effective::Asset.new(:user_id => current_user.try(:id)))
|
|
9
|
+
|
|
10
|
+
@assets = Effective::Asset.where(:user_id => current_user.try(:id))
|
|
11
|
+
@aws_acl = EffectiveAssets.aws_acl.presence || 'public-read'
|
|
12
|
+
|
|
13
|
+
if params[:only] == 'images'
|
|
14
|
+
@assets = @assets.images
|
|
15
|
+
@file_types = [:jpg, :gif, :png, :bmp, :ico]
|
|
16
|
+
@aws_acl = 'public-read' # The CKEditor Insert Image functionality needs a public-read image here
|
|
17
|
+
elsif params[:only] == 'nonimages'
|
|
18
|
+
@assets = @assets.nonimages
|
|
19
|
+
@file_types = [:pdf, :zip, :doc, :docx, :xls, :xlsx, :txt, :avi, :m4v, :m2v, :mov, :mp3, :mp4]
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
@user_uploads = UserUploads.new(@assets)
|
|
23
|
+
|
|
24
|
+
render :file => 'effective/assets/iframe'
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
def destroy
|
|
28
|
+
@asset = Effective::Asset.find(params[:id])
|
|
29
|
+
EffectiveAssets.authorized?(self, :destroy, @asset)
|
|
30
|
+
|
|
31
|
+
if @asset.destroy
|
|
32
|
+
flash[:success] = 'Successfully deleted asset'
|
|
33
|
+
else
|
|
34
|
+
flash[:danger] = 'Unable to delete asset'
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
redirect_to(:back) rescue redirect_to(effective_assets.effective_assets_path)
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
end
|
|
41
|
+
end
|
|
@@ -1,98 +1,82 @@
|
|
|
1
|
-
require 's3_swf_upload'
|
|
2
|
-
require 'base64'
|
|
3
|
-
|
|
4
1
|
module Effective
|
|
5
2
|
class S3UploadsController < ApplicationController
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
respond_to :js, :xml
|
|
9
|
-
|
|
10
|
-
include S3SwfUpload::Signature
|
|
11
|
-
|
|
12
|
-
def index
|
|
13
|
-
# This is actually a 'new' action. Not an index. The s3 flash uploader is hardcoded to check this url as an xml request
|
|
14
|
-
|
|
15
|
-
EffectiveAssets.authorized?(self, :create, Effective::Asset)
|
|
3
|
+
skip_authorization_check if defined?(CanCan)
|
|
4
|
+
skip_before_filter :verify_authenticity_token
|
|
16
5
|
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
secret_key = EffectiveAssets.aws_secret_access_key
|
|
21
|
-
key = params[:key]
|
|
22
|
-
content_type = params[:content_type]
|
|
23
|
-
https = 'false'
|
|
24
|
-
error_message = ''
|
|
25
|
-
expiration_date = 1.hours.from_now.utc.strftime('%Y-%m-%dT%H:%M:%S.000Z')
|
|
6
|
+
# When we create an Asset, we're effectively reserving the ID
|
|
7
|
+
# But the Asset itself isn't really there or uploaded yet.
|
|
8
|
+
# But we want to start uploading to the final s3 path
|
|
26
9
|
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
{'bucket': '#{bucket}'},
|
|
32
|
-
{'key': '#{key}'},
|
|
33
|
-
{'acl': '#{acl}'},
|
|
34
|
-
{'Content-Type': '#{content_type}'},
|
|
35
|
-
{'Content-Disposition': 'attachment'},
|
|
36
|
-
['starts-with', '$Filename', ''],
|
|
37
|
-
['eq', '$success_action_status', '201']
|
|
38
|
-
]
|
|
39
|
-
}").gsub(/\n|\r/, '')
|
|
10
|
+
def create
|
|
11
|
+
# Here we initialize an empty placeholder Asset, so we can reserve the ID
|
|
12
|
+
@asset = Effective::Asset.new(:user_id => ((current_user.try(:id) || 1) rescue 1), :upload_file => 'placeholder')
|
|
13
|
+
@asset.extra = params[:extra] if params[:extra].kind_of?(Hash)
|
|
40
14
|
|
|
41
|
-
|
|
15
|
+
EffectiveAssets.authorized?(self, :create, @asset)
|
|
42
16
|
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
:signature => signature,
|
|
48
|
-
:bucket => bucket,
|
|
49
|
-
:accesskeyid => access_key_id,
|
|
50
|
-
:acl => acl,
|
|
51
|
-
:expirationdate => expiration_date,
|
|
52
|
-
:https => https,
|
|
53
|
-
:errorMessage => error_message.to_s,
|
|
54
|
-
}.to_xml
|
|
55
|
-
}
|
|
17
|
+
if @asset.save
|
|
18
|
+
render(:text => {:id => @asset.id, :s3_key => asset_s3_key(@asset)}.to_json, :status => 200)
|
|
19
|
+
else
|
|
20
|
+
render(:text => '', :status => 400)
|
|
56
21
|
end
|
|
57
22
|
end
|
|
58
23
|
|
|
59
|
-
def
|
|
60
|
-
|
|
24
|
+
def update
|
|
25
|
+
@asset = Effective::Asset.find(params[:id])
|
|
61
26
|
|
|
62
|
-
|
|
63
|
-
if params[:file_path].present?
|
|
64
|
-
asset = Asset.create_from_s3_uploader(params[:file_path],
|
|
65
|
-
{
|
|
66
|
-
:title => params[:title],
|
|
67
|
-
:description => params[:description],
|
|
68
|
-
:tags => params[:tags],
|
|
69
|
-
:content_type => params[:content_type],
|
|
70
|
-
:data_size => params[:file_size],
|
|
71
|
-
:user_id => current_user.try(:id)
|
|
72
|
-
}
|
|
73
|
-
)
|
|
74
|
-
else
|
|
75
|
-
asset = (Asset.find(params[:asset_id].to_i) rescue false)
|
|
76
|
-
end
|
|
27
|
+
EffectiveAssets.authorized?(self, :update, @asset)
|
|
77
28
|
|
|
78
|
-
unless
|
|
79
|
-
|
|
80
|
-
|
|
29
|
+
unless params[:skip_update] # This is useful for the acts_as_asset_box Attach action
|
|
30
|
+
if update_placeholder_asset(@asset, params) == false
|
|
31
|
+
render :text => '', :status => :unprocessable_entity
|
|
32
|
+
return
|
|
33
|
+
end
|
|
81
34
|
end
|
|
82
35
|
|
|
83
36
|
# If the attachment information is present, then our input needs some attachment HTML
|
|
84
|
-
if params.key?(:
|
|
85
|
-
attachment = Attachment.new
|
|
37
|
+
if params.key?(:attachable_object_name)
|
|
38
|
+
attachment = Effective::Attachment.new
|
|
86
39
|
attachment.attachable_type = params[:attachable_type].try(:classify)
|
|
87
|
-
attachment.attachable_id = params[:attachable_id].try(:to_i)
|
|
88
|
-
attachment.asset_id = asset.try(:id)
|
|
40
|
+
attachment.attachable_id = params[:attachable_id].try(:to_i)
|
|
41
|
+
attachment.asset_id = @asset.try(:id)
|
|
89
42
|
attachment.box = params[:box]
|
|
90
43
|
attachment.position = 0
|
|
44
|
+
attachable_object_name = params[:attachable_object_name].to_s
|
|
45
|
+
attachment_actions = params[:attachment_actions]
|
|
46
|
+
|
|
47
|
+
attachment_partial =
|
|
48
|
+
case params[:attachment_style].to_s
|
|
49
|
+
when 'table'
|
|
50
|
+
'attachment_as_table'
|
|
51
|
+
when 'list'
|
|
52
|
+
'attachment_as_list'
|
|
53
|
+
else # :thumbnail, nil, or anything
|
|
54
|
+
'attachment_as_thumbnail'
|
|
55
|
+
end
|
|
91
56
|
|
|
92
|
-
render :partial =>
|
|
57
|
+
render :partial => "asset_box_input/#{attachment_partial}", :locals => {:attachment => attachment, :attachable_object_name => attachable_object_name, :attachment_actions => attachment_actions}, :status => 200, :content_type => 'text/html'
|
|
93
58
|
else
|
|
94
59
|
render :text => '', :status => 200
|
|
95
60
|
end
|
|
96
61
|
end
|
|
62
|
+
|
|
63
|
+
private
|
|
64
|
+
|
|
65
|
+
def update_placeholder_asset(asset, opts)
|
|
66
|
+
asset.upload_file = opts[:upload_file]
|
|
67
|
+
asset.data_size = opts[:data_size]
|
|
68
|
+
asset.content_type = opts[:content_type]
|
|
69
|
+
asset.title = opts[:title]
|
|
70
|
+
asset.aws_acl = opts[:aws_acl]
|
|
71
|
+
asset[:data] = opts[:title]
|
|
72
|
+
|
|
73
|
+
# If our S3 Uploader has any issue uploading/saving the asset, destroy the placeholder empty one
|
|
74
|
+
asset.save ? true : (asset.try(:destroy) and false)
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
def asset_s3_key(asset)
|
|
78
|
+
"#{EffectiveAssets.aws_path.chomp('/')}/#{asset.id.to_i}/${filename}"
|
|
79
|
+
end
|
|
80
|
+
|
|
97
81
|
end
|
|
98
82
|
end
|
|
@@ -14,42 +14,58 @@ module EffectiveAssetsHelper
|
|
|
14
14
|
end
|
|
15
15
|
|
|
16
16
|
opts = opts.merge({:alt => asset.description || asset.title || asset.file_name}).merge(options)
|
|
17
|
-
|
|
17
|
+
|
|
18
|
+
content_tag(:img, nil, opts.merge(:src => _effective_asset_image_url(asset, version))).gsub('"', "'").html_safe
|
|
18
19
|
end
|
|
19
20
|
|
|
20
21
|
def effective_asset_link_to(asset, version = nil, options = {})
|
|
21
|
-
|
|
22
|
+
options_title = options.delete(:title)
|
|
23
|
+
link_title = options_title || asset.title || asset.file_name || asset.description || "Asset ##{asset.id}"
|
|
22
24
|
|
|
23
|
-
|
|
25
|
+
if asset.image?
|
|
26
|
+
link_to(link_title, _effective_asset_image_url(asset, version), options).gsub('"', "'").html_safe # we need all ' quotes or it breaks Insert as functionality
|
|
27
|
+
else
|
|
28
|
+
link_to(link_title, asset.url, options).gsub('"', "'").html_safe # we need all ' quotes or it breaks Insert as functionality
|
|
29
|
+
end
|
|
24
30
|
end
|
|
25
31
|
|
|
26
32
|
def effective_asset_video_tag(asset)
|
|
27
33
|
render(:partial => 'assets/video', :locals => { :asset => asset }).gsub('"', "'").html_safe # we need all ' quotes or it breaks Insert as functionality
|
|
28
34
|
end
|
|
29
35
|
|
|
36
|
+
def effective_asset_title(asset)
|
|
37
|
+
[
|
|
38
|
+
asset.title,
|
|
39
|
+
asset.description,
|
|
40
|
+
asset.tags,
|
|
41
|
+
"Size: #{number_to_human_size(asset.data_size)}",
|
|
42
|
+
"Content Type: #{asset.content_type}"
|
|
43
|
+
].compact.join("\n")
|
|
44
|
+
end
|
|
45
|
+
|
|
30
46
|
def _effective_asset_image_url(asset, version = nil)
|
|
31
|
-
|
|
47
|
+
# asset_url and image_url will work in Rails4
|
|
48
|
+
|
|
49
|
+
return image_path('mime-types/file.png') if !asset.content_type.present? or asset.content_type == 'unknown'
|
|
32
50
|
|
|
33
51
|
if asset.icon?
|
|
34
52
|
asset.url
|
|
35
53
|
elsif asset.image?
|
|
36
|
-
|
|
54
|
+
asset.url(version)
|
|
37
55
|
elsif asset.audio?
|
|
38
|
-
'
|
|
56
|
+
image_path('mime-types/mp3.png')
|
|
39
57
|
elsif asset.video?
|
|
40
|
-
'
|
|
58
|
+
image_path('mime-types/video.png')
|
|
41
59
|
elsif asset.content_type.include? 'msword'
|
|
42
|
-
'
|
|
60
|
+
image_path('mime-types/word.jpg')
|
|
43
61
|
elsif asset.content_type.include? 'excel'
|
|
44
|
-
'
|
|
62
|
+
image_path('mime-types/excel.png')
|
|
45
63
|
elsif asset.content_type.include? 'application/pdf'
|
|
46
|
-
'
|
|
64
|
+
image_path('mime-types/pdf.png')
|
|
47
65
|
elsif asset.content_type.include? 'application/zip'
|
|
48
|
-
'
|
|
66
|
+
image_path('mime-types/zip.png')
|
|
49
67
|
else
|
|
50
|
-
'
|
|
68
|
+
image_path('mime-types/file.png')
|
|
51
69
|
end
|
|
52
70
|
end
|
|
53
|
-
|
|
54
|
-
|
|
55
71
|
end
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
module EffectiveAssetsS3Helper
|
|
2
|
+
|
|
3
|
+
def s3_uploader_fields(options = {})
|
|
4
|
+
S3Uploader.new(options).fields.map do |name, value|
|
|
5
|
+
hidden_field_tag(name, value, :disabled => 'disabled')
|
|
6
|
+
end.join.html_safe
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
def s3_uploader_url
|
|
10
|
+
Effective::Asset.s3_base_path.chomp('/') + '/'
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
# Copied and modified from https://github.com/waynehoover/s3_direct_upload/blob/master/lib/s3_direct_upload/form_helper.rb
|
|
14
|
+
class S3Uploader
|
|
15
|
+
def initialize(options)
|
|
16
|
+
@options = options.reverse_merge(
|
|
17
|
+
aws_access_key_id: EffectiveAssets.aws_access_key_id,
|
|
18
|
+
aws_secret_access_key: EffectiveAssets.aws_secret_access_key,
|
|
19
|
+
bucket: EffectiveAssets.aws_bucket,
|
|
20
|
+
aws_acl: EffectiveAssets.aws_acl,
|
|
21
|
+
expiration: 10.hours.from_now.utc.iso8601,
|
|
22
|
+
max_file_size: 1000.megabytes,
|
|
23
|
+
key_starts_with: "#{EffectiveAssets.aws_path.chomp('/')}/",
|
|
24
|
+
key: '${filename}' # We use an AJAX request to update this key to a useful value
|
|
25
|
+
)
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
def fields
|
|
29
|
+
{
|
|
30
|
+
:key => @options[:key],
|
|
31
|
+
:acl => @options[:aws_acl],
|
|
32
|
+
'AWSAccessKeyId' => @options[:aws_access_key_id],
|
|
33
|
+
:policy => policy,
|
|
34
|
+
:signature => signature,
|
|
35
|
+
:success_action_status => '201',
|
|
36
|
+
'X-Requested-With' => 'xhr'
|
|
37
|
+
}
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
def policy
|
|
41
|
+
Base64.encode64(policy_data.to_json).gsub("\n", "")
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
def policy_data
|
|
45
|
+
{
|
|
46
|
+
expiration: @options[:expiration],
|
|
47
|
+
conditions: [
|
|
48
|
+
['starts-with', '$key', @options[:key_starts_with]],
|
|
49
|
+
['starts-with', '$x-requested-with', ''],
|
|
50
|
+
['content-length-range', 0, @options[:max_file_size]],
|
|
51
|
+
['starts-with','$content-type', @options[:content_type_starts_with] || ''],
|
|
52
|
+
{:bucket => @options[:bucket]},
|
|
53
|
+
{:acl => @options[:aws_acl]},
|
|
54
|
+
{:success_action_status => '201'}
|
|
55
|
+
] + (@options[:conditions] || [])
|
|
56
|
+
}
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
def signature
|
|
60
|
+
Base64.encode64(
|
|
61
|
+
OpenSSL::HMAC.digest(
|
|
62
|
+
OpenSSL::Digest::SHA1.new(),
|
|
63
|
+
@options[:aws_secret_access_key], policy
|
|
64
|
+
)
|
|
65
|
+
).gsub("\n", "")
|
|
66
|
+
end
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
end
|
|
@@ -37,7 +37,6 @@ module ActsAsAssetBox
|
|
|
37
37
|
has_many :attachments, :as => :attachable, :class_name => "Effective::Attachment", :dependent => :delete_all
|
|
38
38
|
has_many :assets, :through => :attachments, :class_name => "Effective::Asset"
|
|
39
39
|
|
|
40
|
-
#attr_accessible :attachments_attributes
|
|
41
40
|
accepts_nested_attributes_for :attachments, :reject_if => :all_blank, :allow_destroy => true
|
|
42
41
|
|
|
43
42
|
# Setup validations
|
|
@@ -45,9 +44,9 @@ module ActsAsAssetBox
|
|
|
45
44
|
if boxes.first.kind_of?(Hash) # We were passed some validation requirements
|
|
46
45
|
boxes = boxes.first
|
|
47
46
|
|
|
48
|
-
@@acts_as_asset_box_boxes = boxes.keys
|
|
49
|
-
|
|
50
47
|
boxes.each do |box, validation|
|
|
48
|
+
self.send(:define_method, box) { assets(box) }
|
|
49
|
+
|
|
51
50
|
if validation == true
|
|
52
51
|
validates box, :asset_box_presence => true
|
|
53
52
|
elsif validation.kind_of?(Integer) or validation.kind_of?(Range)
|
|
@@ -55,11 +54,15 @@ module ActsAsAssetBox
|
|
|
55
54
|
end
|
|
56
55
|
end
|
|
57
56
|
else
|
|
58
|
-
|
|
57
|
+
boxes.each do |key|
|
|
58
|
+
self.send(:define_method, key) { assets(key) }
|
|
59
|
+
end
|
|
59
60
|
end
|
|
60
61
|
|
|
61
62
|
class_eval do
|
|
62
63
|
def attachments_attributes=(atts)
|
|
64
|
+
@last_atts == atts ? return : @last_atts = atts
|
|
65
|
+
|
|
63
66
|
current_box = ''; position = 0
|
|
64
67
|
|
|
65
68
|
atts.each do |k, v|
|
|
@@ -67,7 +70,7 @@ module ActsAsAssetBox
|
|
|
67
70
|
atts[k]['position'] = (position += 1) if atts[k]['_destroy'] != '1'
|
|
68
71
|
end
|
|
69
72
|
|
|
70
|
-
assign_nested_attributes_for_collection_association(:attachments, atts
|
|
73
|
+
assign_nested_attributes_for_collection_association(:attachments, atts)
|
|
71
74
|
end
|
|
72
75
|
end
|
|
73
76
|
end
|
|
@@ -77,11 +80,12 @@ module ActsAsAssetBox
|
|
|
77
80
|
|
|
78
81
|
def assets(box = nil)
|
|
79
82
|
box = (box.present? ? box.to_s : 'assets')
|
|
83
|
+
boxes = box.pluralize
|
|
80
84
|
|
|
81
|
-
if box ==
|
|
82
|
-
attachments.
|
|
85
|
+
if box == boxes
|
|
86
|
+
attachments.map { |attachment| attachment.asset if attachment.box == boxes }.compact
|
|
83
87
|
else
|
|
84
|
-
attachments.to_a.find { |attachment| attachment.box ==
|
|
88
|
+
attachments.to_a.find { |attachment| attachment.box == boxes }.try(:asset)
|
|
85
89
|
end
|
|
86
90
|
end
|
|
87
91
|
|
|
@@ -89,9 +93,69 @@ module ActsAsAssetBox
|
|
|
89
93
|
assets(:asset)
|
|
90
94
|
end
|
|
91
95
|
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
96
|
+
def add_to_asset_box(box, *items)
|
|
97
|
+
box = (box.present? ? box.to_s : 'assets')
|
|
98
|
+
boxes = box.pluralize
|
|
99
|
+
items = [items].flatten.compact
|
|
100
|
+
|
|
101
|
+
if items.present? && items.any? { |obj| !obj.kind_of?(Effective::Asset) }
|
|
102
|
+
raise ArgumentError.new('add_to_asset_box expects one or more Effective::Assets, or an Array of Effective::Assets')
|
|
103
|
+
end
|
|
104
|
+
|
|
105
|
+
if box == boxes # If we're adding to a pluralized box, we want to add our attachment onto the end
|
|
106
|
+
pos = attachments.select { |attachment| attachment.box == boxes }.last.try(:position).to_i + 1
|
|
107
|
+
else # If we're adding to a singular box, we want our attachments to be on the front
|
|
108
|
+
pos = attachments.to_a.find { |attachment| attachment.box == boxes }.try(:position).to_i
|
|
109
|
+
|
|
110
|
+
# Push all the attachments forward
|
|
111
|
+
attachments.each { |att| att.position = (att.position + items.length) if att.box == boxes }
|
|
112
|
+
end
|
|
113
|
+
|
|
114
|
+
# Build the attachments
|
|
115
|
+
items.each_with_index do |item, x|
|
|
116
|
+
attachment = self.attachments.build(:position => (pos+x), :box => boxes)
|
|
117
|
+
|
|
118
|
+
attachment.attachable = self
|
|
119
|
+
attachment.asset = item
|
|
120
|
+
end
|
|
121
|
+
|
|
122
|
+
attachments.to_a.sort_by!(&:position)
|
|
123
|
+
|
|
124
|
+
true
|
|
125
|
+
end
|
|
126
|
+
|
|
127
|
+
def add_to_asset_box!(box, *items)
|
|
128
|
+
add_to_asset_box(box, items) && save!
|
|
129
|
+
end
|
|
130
|
+
|
|
131
|
+
# The idea here is that if you want to replace an Asset with Another one
|
|
132
|
+
# the Attachment should keep the same order, and only the asset should change
|
|
133
|
+
|
|
134
|
+
def replace_in_asset_box(box, original, overwrite)
|
|
135
|
+
box = (box.present? ? box.to_s : 'assets')
|
|
136
|
+
boxes = box.pluralize
|
|
137
|
+
|
|
138
|
+
unless original.present? && original.kind_of?(Effective::Asset)
|
|
139
|
+
raise ArgumentError.new("second parameter 'original' must be a single Effective::Asset")
|
|
140
|
+
end
|
|
141
|
+
|
|
142
|
+
unless overwrite.present? && overwrite.kind_of?(Effective::Asset)
|
|
143
|
+
raise ArgumentError.new("third parameter 'overwrite' must be a single Effective::Asset")
|
|
144
|
+
end
|
|
145
|
+
|
|
146
|
+
attachment = attachments.to_a.find { |attachment| attachment.box == boxes && attachment.asset == original }
|
|
147
|
+
|
|
148
|
+
if attachment.present?
|
|
149
|
+
attachment.asset = overwrite
|
|
150
|
+
true
|
|
151
|
+
else
|
|
152
|
+
false
|
|
153
|
+
end
|
|
154
|
+
end
|
|
155
|
+
|
|
156
|
+
def replace_in_asset_box!(box, original, overwrite)
|
|
157
|
+
replace_in_asset_box(box, original, overwrite) && save!
|
|
95
158
|
end
|
|
159
|
+
|
|
96
160
|
end
|
|
97
161
|
|