universal_s3_uploader 0.0.2
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
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
---
|
|
2
|
+
SHA1:
|
|
3
|
+
metadata.gz: ad4e7559307ef43646f64635419a558a23bf30ea
|
|
4
|
+
data.tar.gz: 8a1d368ad92187f46bd3002ab2680d06a331564d
|
|
5
|
+
SHA512:
|
|
6
|
+
metadata.gz: a6ae6dcf83495dc7316c19edba7c0fbc8e6036ea5c9c98d0132c28e8a5b08a87488d0ba008c81a672df96a946da2713d764fff46a62c7e04dcd13f7072f8d82f
|
|
7
|
+
data.tar.gz: 0be4722c7c6727db0b818e6ffc2ccfc79d88ea57568be4e90ae39d766853f6e0550fa74d24e4526fc9f61288f6f72dba28029b47f9b04db4c9164cb442a33865
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
require 'base64'
|
|
2
|
+
require 'openssl'
|
|
3
|
+
require 'digest/sha1'
|
|
4
|
+
require 'action_view'
|
|
5
|
+
require 'rails'
|
|
6
|
+
|
|
7
|
+
module UniversalS3Uploader
|
|
8
|
+
module ViewHelper
|
|
9
|
+
def universal_s3_uploader_tag(key, policy_name, options = {})
|
|
10
|
+
uh = UploaderHelper.new(policy_name)
|
|
11
|
+
|
|
12
|
+
form_tag(uh.url, {method: 'POST', enctype: 'multipart/form-data', authenticity_token: false, class: 'universal_s3_uploader'}.merge(options)) do
|
|
13
|
+
uh.tags(key).html_safe
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
class UploaderHelper
|
|
18
|
+
def initialize(policy_name)
|
|
19
|
+
@config = YAML.load_file("#{Rails.root.to_s}/config/amazon.yml")
|
|
20
|
+
set_policy(policy_name)
|
|
21
|
+
set_bucket
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
# set expiration time
|
|
25
|
+
def set_policy(policy_name)
|
|
26
|
+
@policy = @config[policy_name]
|
|
27
|
+
@policy['conditions'] << ["starts-with", "$Filename", ""] # for Flash upload
|
|
28
|
+
if @policy['expiration'] == '' || @policy['expiration'].nil?
|
|
29
|
+
@policy['expiration'] = 1.hour.from_now.iso8601
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
# extract bucket name
|
|
34
|
+
def set_bucket
|
|
35
|
+
@policy['conditions'].each do |condition|
|
|
36
|
+
if condition.class == Hash && condition.keys.first == 'bucket'
|
|
37
|
+
@bucket = condition.values.first
|
|
38
|
+
return
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
raise 'No bucket name in policy Exception'
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
def tags(key)
|
|
46
|
+
av = ActionView::Base.new
|
|
47
|
+
tag = ''
|
|
48
|
+
|
|
49
|
+
([{key: key}] + @policy['conditions']).each do |condition|
|
|
50
|
+
if condition.class == Hash
|
|
51
|
+
tag += av.hidden_field_tag condition.keys.first, condition.values.first, id: nil
|
|
52
|
+
elsif condition.class == Array
|
|
53
|
+
if condition[0] == 'eq' || condition[0] == 'starts-with'
|
|
54
|
+
tag += av.hidden_field_tag condition[1][1..-1], condition[2], id: nil unless condition[1] == '$key'
|
|
55
|
+
end
|
|
56
|
+
else
|
|
57
|
+
raise 'Something in policy unexpected'
|
|
58
|
+
end
|
|
59
|
+
end
|
|
60
|
+
tag += av.hidden_field_tag :AWSAccessKeyId, @config['access_key_id'], id: nil
|
|
61
|
+
tag += av.hidden_field_tag :Policy, policy_encoded, id: nil
|
|
62
|
+
tag += av.hidden_field_tag :Signature, signature, id: nil
|
|
63
|
+
tag += av.file_field_tag :file, multiple: true, accept: 'image/*'
|
|
64
|
+
|
|
65
|
+
tag += '<object id="swfUploader" classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=11,1,0,0">'
|
|
66
|
+
tag += '<param name="movie" value="/assets/S3Uploader.swf">'
|
|
67
|
+
tag += '<param name="wmode" value="transparent">'
|
|
68
|
+
tag += '</object>'
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
def bucket
|
|
72
|
+
@bucket
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
def url
|
|
76
|
+
"http://#{@bucket}.s3.amazonaws.com"
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
def policy_encoded
|
|
80
|
+
Base64.encode64(@policy.to_json).gsub("\n","")
|
|
81
|
+
end
|
|
82
|
+
|
|
83
|
+
def signature
|
|
84
|
+
Base64.encode64(OpenSSL::HMAC.digest(OpenSSL::Digest::Digest.new('sha1'), @config['secret_access_key'], policy_encoded)).gsub("\n","")
|
|
85
|
+
end
|
|
86
|
+
end
|
|
87
|
+
end
|
|
88
|
+
end
|
|
89
|
+
|
|
90
|
+
class ActionView::Base
|
|
91
|
+
include UniversalS3Uploader::ViewHelper
|
|
92
|
+
end
|
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
package
|
|
2
|
+
{
|
|
3
|
+
import flash.display.Sprite;
|
|
4
|
+
import flash.events.MouseEvent;
|
|
5
|
+
import flash.net.FileReferenceList;
|
|
6
|
+
import flash.events.Event;
|
|
7
|
+
import flash.net.FileReference;
|
|
8
|
+
import flash.external.ExternalInterface;
|
|
9
|
+
import flash.net.URLVariables;
|
|
10
|
+
import flash.net.URLRequest;
|
|
11
|
+
import flash.net.URLRequestMethod;
|
|
12
|
+
import flash.net.FileFilter;
|
|
13
|
+
import flash.events.ProgressEvent;
|
|
14
|
+
import flash.display.Stage;
|
|
15
|
+
import flash.events.DataEvent;
|
|
16
|
+
|
|
17
|
+
public class S3Uploader extends Sprite
|
|
18
|
+
{
|
|
19
|
+
private var button;
|
|
20
|
+
private var files;
|
|
21
|
+
private var params;
|
|
22
|
+
|
|
23
|
+
private function log(str:*):void
|
|
24
|
+
{
|
|
25
|
+
ExternalInterface.call("console.log", str);
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
public function S3Uploader()
|
|
29
|
+
{
|
|
30
|
+
getRequestData();
|
|
31
|
+
makeButton();
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
private function getRequestData()
|
|
35
|
+
{
|
|
36
|
+
if (ExternalInterface.available)
|
|
37
|
+
{
|
|
38
|
+
params = new URLVariables();
|
|
39
|
+
ExternalInterface.addCallback("sendFormData", receiveFormData);
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
private function receiveFormData(name:String, value:String):void
|
|
44
|
+
{
|
|
45
|
+
params[name] = value;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
private function makeButton():void
|
|
49
|
+
{
|
|
50
|
+
button = new Sprite();
|
|
51
|
+
button.graphics.beginFill(0x0000ff, 0);
|
|
52
|
+
button.graphics.drawRect(0,0,100,100);
|
|
53
|
+
button.graphics.endFill();
|
|
54
|
+
button.buttonMode = true;
|
|
55
|
+
button.addEventListener(MouseEvent.CLICK, clickHandler);
|
|
56
|
+
|
|
57
|
+
addChild(button);
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
private function clickHandler(evt:MouseEvent):void
|
|
61
|
+
{
|
|
62
|
+
files = new FileReferenceList();
|
|
63
|
+
files.addEventListener(Event.SELECT, selectHandler);
|
|
64
|
+
|
|
65
|
+
var imageTypes:FileFilter = new FileFilter("Images (*.jpg, *.jpeg, *.gif, *.png)", "*.jpg; *.jpeg; *.gif; *.png");
|
|
66
|
+
files.browse(new Array(imageTypes));
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
private function selectHandler(evt:Event):void
|
|
70
|
+
{
|
|
71
|
+
var index = 0;
|
|
72
|
+
for each (var file in files.fileList)
|
|
73
|
+
{
|
|
74
|
+
upload(file, index++);
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
private function upload(file:FileReference, index:int):void
|
|
79
|
+
{
|
|
80
|
+
var request:URLRequest = new URLRequest('http://' + params["bucket"] + '.s3.amazonaws.com');
|
|
81
|
+
request.method = URLRequestMethod.POST;
|
|
82
|
+
request.data = params;
|
|
83
|
+
|
|
84
|
+
function passIndex(func:Function):Function
|
|
85
|
+
{
|
|
86
|
+
return function handler(evt:Event):void { func(index, evt); }
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
file.addEventListener(Event.OPEN, passIndex(openHandler));
|
|
90
|
+
file.addEventListener(ProgressEvent.PROGRESS, passIndex(progressHandler));
|
|
91
|
+
file.addEventListener(Event.COMPLETE, passIndex(completeHandler));
|
|
92
|
+
file.addEventListener(DataEvent.UPLOAD_COMPLETE_DATA, passIndex(uploadCompleteDataHandler));
|
|
93
|
+
|
|
94
|
+
file.upload(request, 'file');
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
private function openHandler(index:int, evt:Event):void
|
|
98
|
+
{
|
|
99
|
+
ExternalInterface.call("$('form.universal_s3_uploader').universal_s3_uploader().options.onLoadstart", index);
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
private function progressHandler(index:int, evt:ProgressEvent):void
|
|
103
|
+
{
|
|
104
|
+
var event = new Object();
|
|
105
|
+
event.loaded = evt.bytesLoaded;
|
|
106
|
+
event.total = evt.bytesTotal;
|
|
107
|
+
ExternalInterface.call("$('form.universal_s3_uploader').universal_s3_uploader().options.onProgress", index, event);
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
private function completeHandler(index:int, evt:Event):void
|
|
111
|
+
{
|
|
112
|
+
ExternalInterface.call("$('form.universal_s3_uploader').universal_s3_uploader().options.onSuccess", index);
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
private function uploadCompleteDataHandler(index:int, evt:DataEvent):void
|
|
116
|
+
{
|
|
117
|
+
ExternalInterface.call("$('form.universal_s3_uploader').universal_s3_uploader().options.onResponse", evt.data);
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
}
|
|
Binary file
|
|
Binary file
|
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
(function($)
|
|
2
|
+
{
|
|
3
|
+
$.fn.universal_s3_uploader = function(options)
|
|
4
|
+
{
|
|
5
|
+
if (this.length > 1)
|
|
6
|
+
{
|
|
7
|
+
this.each(function()
|
|
8
|
+
{
|
|
9
|
+
$(this).universal_s3_uploader(options);
|
|
10
|
+
});
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
if (!this.universalS3UploaderInstance)
|
|
14
|
+
{
|
|
15
|
+
this.universalS3UploaderInstance = new UniversalS3Uploader(this, options);
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
return this.universalS3UploaderInstance;
|
|
19
|
+
};
|
|
20
|
+
|
|
21
|
+
var defaultOptions =
|
|
22
|
+
{
|
|
23
|
+
onLoadstart: function(index, event)
|
|
24
|
+
{
|
|
25
|
+
console.log(index + " will be uploaded.");
|
|
26
|
+
},
|
|
27
|
+
onProgress: function(index, event)
|
|
28
|
+
{
|
|
29
|
+
var percentage = Math.round(event.loaded * 100 / event.total);
|
|
30
|
+
console.log(percentage + " %");
|
|
31
|
+
},
|
|
32
|
+
onSuccess: function(index, event)
|
|
33
|
+
{
|
|
34
|
+
console.log(index + " was successfully uploaded.");
|
|
35
|
+
},
|
|
36
|
+
onResponse: function(response)
|
|
37
|
+
{
|
|
38
|
+
console.log(response);
|
|
39
|
+
}
|
|
40
|
+
};
|
|
41
|
+
|
|
42
|
+
var supportFormData = window.FormData;
|
|
43
|
+
|
|
44
|
+
UniversalS3Uploader = (function()
|
|
45
|
+
{
|
|
46
|
+
function UniversalS3Uploader(element, options)
|
|
47
|
+
{
|
|
48
|
+
this.element = $(element);
|
|
49
|
+
this.options = $.extend({}, defaultOptions, options);
|
|
50
|
+
|
|
51
|
+
this.init();
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
UniversalS3Uploader.prototype.init = function()
|
|
55
|
+
{
|
|
56
|
+
this.element.children('div').remove();
|
|
57
|
+
|
|
58
|
+
if (supportFormData) // if supports HTML5 FormData
|
|
59
|
+
{
|
|
60
|
+
this.element.children('object#swfUploader').remove();
|
|
61
|
+
|
|
62
|
+
this.element.children('input[type=file]').change(function()
|
|
63
|
+
{
|
|
64
|
+
$(this).parent().trigger('submit');
|
|
65
|
+
$(this).replaceWith($(this).clone(true));
|
|
66
|
+
});
|
|
67
|
+
|
|
68
|
+
this.element.submit($.proxy(this.submit, this));
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
else // use Flash uploader
|
|
72
|
+
{
|
|
73
|
+
var flashObject = this.element.children('object').get(0);
|
|
74
|
+
|
|
75
|
+
var fileField = this.element.children('input[type=file]');
|
|
76
|
+
|
|
77
|
+
$(flashObject).css("height", fileField.height()+10 + "px").css("width", fileField.width() + "px");
|
|
78
|
+
$(flashObject).css("position", "relative").css("left", "-" + fileField.width() + "px").css("top", "6px");
|
|
79
|
+
|
|
80
|
+
this.element.children('input[type=hidden]').each(function()
|
|
81
|
+
{
|
|
82
|
+
flashObject.sendFormData(this.name, this.value);
|
|
83
|
+
});
|
|
84
|
+
}
|
|
85
|
+
};
|
|
86
|
+
|
|
87
|
+
UniversalS3Uploader.prototype.submit = function()
|
|
88
|
+
{
|
|
89
|
+
var files = this.element.children('input[type=file]').get(0).files || [this.element.children('input[type=file]').val()];
|
|
90
|
+
for (var i = 0, len = files.length; i < len; i++) this.upload(files[i], i);
|
|
91
|
+
|
|
92
|
+
return false;
|
|
93
|
+
};
|
|
94
|
+
|
|
95
|
+
UniversalS3Uploader.prototype.upload = function(file, index)
|
|
96
|
+
{
|
|
97
|
+
var fd = new FormData();
|
|
98
|
+
this.element.children('input[type=hidden]').each(function()
|
|
99
|
+
{
|
|
100
|
+
fd.append(this.name, this.value);
|
|
101
|
+
});
|
|
102
|
+
fd.append('file', file);
|
|
103
|
+
|
|
104
|
+
function passIndex(func)
|
|
105
|
+
{
|
|
106
|
+
return function(event) { $.proxy(func, this)(index, event); }
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
var onResponse = this.options.onResponse;
|
|
110
|
+
function callResponseHandler(event)
|
|
111
|
+
{
|
|
112
|
+
onResponse(this.response);
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
var xhr = new XMLHttpRequest();
|
|
116
|
+
|
|
117
|
+
xhr.addEventListener("loadstart", passIndex(this.options.onLoadstart), false);
|
|
118
|
+
xhr.upload.addEventListener("progress", passIndex(this.options.onProgress), false);
|
|
119
|
+
xhr.addEventListener("load", passIndex(this.options.onSuccess), false);
|
|
120
|
+
xhr.addEventListener("load", callResponseHandler, false);
|
|
121
|
+
|
|
122
|
+
xhr.open('POST', this.element.attr('action'), true);
|
|
123
|
+
xhr.send(fd);
|
|
124
|
+
};
|
|
125
|
+
|
|
126
|
+
return UniversalS3Uploader;
|
|
127
|
+
})();
|
|
128
|
+
})(jQuery);
|
metadata
ADDED
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
|
2
|
+
name: universal_s3_uploader
|
|
3
|
+
version: !ruby/object:Gem::Version
|
|
4
|
+
version: 0.0.2
|
|
5
|
+
platform: ruby
|
|
6
|
+
authors:
|
|
7
|
+
- Dohan Kim
|
|
8
|
+
autorequire:
|
|
9
|
+
bindir: bin
|
|
10
|
+
cert_chain: []
|
|
11
|
+
date: 2014-04-05 00:00:00.000000000 Z
|
|
12
|
+
dependencies: []
|
|
13
|
+
description: This library helps you to upload files to the Amazon S3 Server with AJAX
|
|
14
|
+
techniques in almost of browser environments such as IE, FF and Chrome.
|
|
15
|
+
email:
|
|
16
|
+
- hodoli2776@kaist.ac.kr
|
|
17
|
+
executables: []
|
|
18
|
+
extensions: []
|
|
19
|
+
extra_rdoc_files: []
|
|
20
|
+
files:
|
|
21
|
+
- lib/universal_s3_uploader.rb
|
|
22
|
+
- vendor/assets/flash/S3Uploader.as
|
|
23
|
+
- vendor/assets/flash/S3Uploader.fla
|
|
24
|
+
- vendor/assets/flash/S3Uploader.swf
|
|
25
|
+
- vendor/assets/javascripts/universal_s3_uploader.js
|
|
26
|
+
homepage: http://rubygems.org/gems/universal_s3_uploader
|
|
27
|
+
licenses:
|
|
28
|
+
- MIT
|
|
29
|
+
metadata: {}
|
|
30
|
+
post_install_message:
|
|
31
|
+
rdoc_options: []
|
|
32
|
+
require_paths:
|
|
33
|
+
- lib
|
|
34
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
|
35
|
+
requirements:
|
|
36
|
+
- - '>='
|
|
37
|
+
- !ruby/object:Gem::Version
|
|
38
|
+
version: '0'
|
|
39
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
40
|
+
requirements:
|
|
41
|
+
- - '>='
|
|
42
|
+
- !ruby/object:Gem::Version
|
|
43
|
+
version: '0'
|
|
44
|
+
requirements: []
|
|
45
|
+
rubyforge_project:
|
|
46
|
+
rubygems_version: 2.2.2
|
|
47
|
+
signing_key:
|
|
48
|
+
specification_version: 4
|
|
49
|
+
summary: the AJAX S3 Uploader working in Cross Browser
|
|
50
|
+
test_files: []
|