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: []