condo 1.0.4 → 1.0.6
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/README.textile +133 -133
- data/app/assets/javascripts/condo.js +9 -6
- data/app/assets/javascripts/condo/amazon.js +403 -406
- data/app/assets/javascripts/condo/condo.js +184 -0
- data/app/assets/javascripts/condo/config.js +69 -80
- data/app/assets/javascripts/condo/google.js +338 -255
- data/app/assets/javascripts/condo/md5/hash.worker.emulator.js +23 -23
- data/app/assets/javascripts/condo/md5/hash.worker.js +11 -11
- data/app/assets/javascripts/condo/md5/hasher.js +119 -100
- data/app/assets/javascripts/condo/md5/spark-md5.js +276 -161
- data/app/assets/javascripts/condo/rackspace.js +326 -329
- data/app/assets/javascripts/condo/{abstract-md5.js.erb → services/abstract-md5.js.erb} +86 -93
- data/app/assets/javascripts/condo/{base64.js → services/base64.js} +2 -10
- data/app/assets/javascripts/condo/services/broadcaster.js +26 -0
- data/app/assets/javascripts/condo/services/uploader.js +302 -0
- data/app/assets/javascripts/core/core.js +4 -0
- data/app/assets/javascripts/core/services/1-safe-apply.js +17 -0
- data/app/assets/javascripts/core/services/2-messaging.js +171 -0
- data/lib/condo.rb +269 -269
- data/lib/condo/configuration.rb +137 -139
- data/lib/condo/errors.rb +8 -8
- data/lib/condo/strata/amazon_s3.rb +301 -301
- data/lib/condo/strata/google_cloud_storage.rb +315 -314
- data/lib/condo/strata/rackspace_cloud_files.rb +245 -223
- data/lib/condo/version.rb +1 -1
- metadata +21 -44
- data/app/assets/javascripts/condo/broadcaster.js +0 -60
- data/app/assets/javascripts/condo/controller.js +0 -194
- data/app/assets/javascripts/condo/uploader.js +0 -310
- data/test/dummy/db/test.sqlite3 +0 -0
- data/test/dummy/log/test.log +0 -25
data/lib/condo/version.rb
CHANGED
metadata
CHANGED
@@ -1,62 +1,41 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: condo
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.0.
|
5
|
-
prerelease:
|
4
|
+
version: 1.0.6
|
6
5
|
platform: ruby
|
7
6
|
authors:
|
8
7
|
- Stephen von Takach
|
9
8
|
autorequire:
|
10
9
|
bindir: bin
|
11
10
|
cert_chain: []
|
12
|
-
date:
|
11
|
+
date: 2014-09-20 00:00:00.000000000 Z
|
13
12
|
dependencies:
|
14
13
|
- !ruby/object:Gem::Dependency
|
15
14
|
name: rails
|
16
15
|
requirement: !ruby/object:Gem::Requirement
|
17
|
-
none: false
|
18
16
|
requirements:
|
19
|
-
- -
|
17
|
+
- - '>='
|
20
18
|
- !ruby/object:Gem::Version
|
21
|
-
version:
|
19
|
+
version: 4.0.0
|
22
20
|
type: :runtime
|
23
21
|
prerelease: false
|
24
22
|
version_requirements: !ruby/object:Gem::Requirement
|
25
|
-
none: false
|
26
23
|
requirements:
|
27
|
-
- -
|
24
|
+
- - '>='
|
28
25
|
- !ruby/object:Gem::Version
|
29
|
-
version:
|
26
|
+
version: 4.0.0
|
30
27
|
- !ruby/object:Gem::Dependency
|
31
28
|
name: fog
|
32
29
|
requirement: !ruby/object:Gem::Requirement
|
33
|
-
none: false
|
34
30
|
requirements:
|
35
|
-
- -
|
31
|
+
- - '>='
|
36
32
|
- !ruby/object:Gem::Version
|
37
33
|
version: '0'
|
38
34
|
type: :runtime
|
39
35
|
prerelease: false
|
40
36
|
version_requirements: !ruby/object:Gem::Requirement
|
41
|
-
none: false
|
42
37
|
requirements:
|
43
|
-
- -
|
44
|
-
- !ruby/object:Gem::Version
|
45
|
-
version: '0'
|
46
|
-
- !ruby/object:Gem::Dependency
|
47
|
-
name: sqlite3
|
48
|
-
requirement: !ruby/object:Gem::Requirement
|
49
|
-
none: false
|
50
|
-
requirements:
|
51
|
-
- - ! '>='
|
52
|
-
- !ruby/object:Gem::Version
|
53
|
-
version: '0'
|
54
|
-
type: :development
|
55
|
-
prerelease: false
|
56
|
-
version_requirements: !ruby/object:Gem::Requirement
|
57
|
-
none: false
|
58
|
-
requirements:
|
59
|
-
- - ! '>='
|
38
|
+
- - '>='
|
60
39
|
- !ruby/object:Gem::Version
|
61
40
|
version: '0'
|
62
41
|
description: Provides signed upload signatures to your users browsers so they can
|
@@ -67,20 +46,23 @@ executables: []
|
|
67
46
|
extensions: []
|
68
47
|
extra_rdoc_files: []
|
69
48
|
files:
|
70
|
-
- app/assets/javascripts/condo/abstract-md5.js.erb
|
71
49
|
- app/assets/javascripts/condo/amazon.js
|
72
|
-
- app/assets/javascripts/condo/
|
73
|
-
- app/assets/javascripts/condo/broadcaster.js
|
50
|
+
- app/assets/javascripts/condo/condo.js
|
74
51
|
- app/assets/javascripts/condo/config.js
|
75
|
-
- app/assets/javascripts/condo/controller.js
|
76
52
|
- app/assets/javascripts/condo/google.js
|
77
53
|
- app/assets/javascripts/condo/md5/hash.worker.emulator.js
|
78
54
|
- app/assets/javascripts/condo/md5/hash.worker.js
|
79
55
|
- app/assets/javascripts/condo/md5/hasher.js
|
80
56
|
- app/assets/javascripts/condo/md5/spark-md5.js
|
81
57
|
- app/assets/javascripts/condo/rackspace.js
|
82
|
-
- app/assets/javascripts/condo/
|
58
|
+
- app/assets/javascripts/condo/services/abstract-md5.js.erb
|
59
|
+
- app/assets/javascripts/condo/services/base64.js
|
60
|
+
- app/assets/javascripts/condo/services/broadcaster.js
|
61
|
+
- app/assets/javascripts/condo/services/uploader.js
|
83
62
|
- app/assets/javascripts/condo.js
|
63
|
+
- app/assets/javascripts/core/core.js
|
64
|
+
- app/assets/javascripts/core/services/1-safe-apply.js
|
65
|
+
- app/assets/javascripts/core/services/2-messaging.js
|
84
66
|
- lib/condo/configuration.rb
|
85
67
|
- lib/condo/engine.rb
|
86
68
|
- lib/condo/errors.rb
|
@@ -115,8 +97,6 @@ files:
|
|
115
97
|
- test/dummy/config/locales/en.yml
|
116
98
|
- test/dummy/config/routes.rb
|
117
99
|
- test/dummy/config.ru
|
118
|
-
- test/dummy/db/test.sqlite3
|
119
|
-
- test/dummy/log/test.log
|
120
100
|
- test/dummy/public/404.html
|
121
101
|
- test/dummy/public/422.html
|
122
102
|
- test/dummy/public/500.html
|
@@ -128,27 +108,26 @@ files:
|
|
128
108
|
- test/test_helper.rb
|
129
109
|
homepage: http://cotag.me/
|
130
110
|
licenses: []
|
111
|
+
metadata: {}
|
131
112
|
post_install_message:
|
132
113
|
rdoc_options: []
|
133
114
|
require_paths:
|
134
115
|
- lib
|
135
116
|
required_ruby_version: !ruby/object:Gem::Requirement
|
136
|
-
none: false
|
137
117
|
requirements:
|
138
|
-
- -
|
118
|
+
- - '>='
|
139
119
|
- !ruby/object:Gem::Version
|
140
120
|
version: '0'
|
141
121
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
142
|
-
none: false
|
143
122
|
requirements:
|
144
|
-
- -
|
123
|
+
- - '>='
|
145
124
|
- !ruby/object:Gem::Version
|
146
125
|
version: '0'
|
147
126
|
requirements: []
|
148
127
|
rubyforge_project:
|
149
|
-
rubygems_version:
|
128
|
+
rubygems_version: 2.0.14
|
150
129
|
signing_key:
|
151
|
-
specification_version:
|
130
|
+
specification_version: 4
|
152
131
|
summary: Direct Cloud Storage Uploader
|
153
132
|
test_files:
|
154
133
|
- test/condo_test.rb
|
@@ -173,8 +152,6 @@ test_files:
|
|
173
152
|
- test/dummy/config/locales/en.yml
|
174
153
|
- test/dummy/config/routes.rb
|
175
154
|
- test/dummy/config.ru
|
176
|
-
- test/dummy/db/test.sqlite3
|
177
|
-
- test/dummy/log/test.log
|
178
155
|
- test/dummy/public/404.html
|
179
156
|
- test/dummy/public/422.html
|
180
157
|
- test/dummy/public/500.html
|
@@ -1,60 +0,0 @@
|
|
1
|
-
/**
|
2
|
-
* CoTag Condo Amazon S3 Strategy
|
3
|
-
* Direct to cloud resumable uploads for Google Cloud Storage
|
4
|
-
*
|
5
|
-
* Copyright (c) 2012 CoTag Media.
|
6
|
-
*
|
7
|
-
* @author Stephen von Takach <steve@cotag.me>
|
8
|
-
* @copyright 2012 cotag.me
|
9
|
-
*
|
10
|
-
*
|
11
|
-
* References:
|
12
|
-
* * https://github.com/umdjs/umd
|
13
|
-
* * https://github.com/addyosmani/jquery-plugin-patterns
|
14
|
-
* *
|
15
|
-
*
|
16
|
-
**/
|
17
|
-
|
18
|
-
(function (factory) {
|
19
|
-
if (typeof define === 'function' && define.amd) {
|
20
|
-
// AMD
|
21
|
-
define('condo-broadcaster', factory);
|
22
|
-
} else {
|
23
|
-
// Browser globals
|
24
|
-
factory();
|
25
|
-
}
|
26
|
-
}(function (undefined) {
|
27
|
-
'use strict';
|
28
|
-
|
29
|
-
|
30
|
-
//
|
31
|
-
//
|
32
|
-
//
|
33
|
-
|
34
|
-
|
35
|
-
angular.module('CondoBroadcaster', []).factory('Condo.Broadcast', ['$rootScope', function($rootScope) {
|
36
|
-
// eventBroadcaster is the object created by the factory method.
|
37
|
-
var eventBroadcaster = {};
|
38
|
-
|
39
|
-
// The message is a string or object to carry data with the event.
|
40
|
-
eventBroadcaster.message = {};
|
41
|
-
|
42
|
-
// The event name is a string used to define event types.
|
43
|
-
eventBroadcaster.eventName = '';
|
44
|
-
|
45
|
-
// This method is called from within a controller to define an event and attach data to the eventBroadcaster object.
|
46
|
-
eventBroadcaster.broadcast = function(evName, msg) {
|
47
|
-
this.message = msg;
|
48
|
-
this.eventName = evName;
|
49
|
-
this.broadcastItem();
|
50
|
-
};
|
51
|
-
|
52
|
-
// This method broadcasts an event with the specified name.
|
53
|
-
eventBroadcaster.broadcastItem = function() {
|
54
|
-
$rootScope.$broadcast(this.eventName);
|
55
|
-
};
|
56
|
-
|
57
|
-
return eventBroadcaster;
|
58
|
-
}]);
|
59
|
-
|
60
|
-
}));
|
@@ -1,194 +0,0 @@
|
|
1
|
-
/**
|
2
|
-
* CoTag Condo
|
3
|
-
* Direct to cloud resumable uploads
|
4
|
-
*
|
5
|
-
* Copyright (c) 2012 CoTag Media.
|
6
|
-
*
|
7
|
-
* @author Stephen von Takach <steve@cotag.me>
|
8
|
-
* @copyright 2012 cotag.me
|
9
|
-
*
|
10
|
-
*
|
11
|
-
* References:
|
12
|
-
* * https://github.com/umdjs/umd
|
13
|
-
* * https://github.com/addyosmani/jquery-plugin-patterns
|
14
|
-
* * http://ericterpstra.com/2012/09/angular-cats-part-3-communicating-with-broadcast/
|
15
|
-
* * http://docs.angularjs.org/api/ng.$rootScope.Scope#$watch
|
16
|
-
*
|
17
|
-
**/
|
18
|
-
|
19
|
-
(function (factory) {
|
20
|
-
if (typeof define === 'function' && define.amd) {
|
21
|
-
// AMD
|
22
|
-
define('condo-controller', ['jquery', 'condo-uploader'], factory);
|
23
|
-
} else {
|
24
|
-
// Browser globals
|
25
|
-
factory(jQuery, window.CondoUploader);
|
26
|
-
}
|
27
|
-
}(function ($, uploads, undefined) {
|
28
|
-
'use strict';
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
//
|
33
|
-
// Create a controller for managing the upload states
|
34
|
-
//
|
35
|
-
uploads.controller('Condo.Controller', ['$scope', 'Condo.Api', 'Condo.Broadcast', 'Condo.Config', function($scope, api, broadcaster, config) {
|
36
|
-
|
37
|
-
$scope.uploads = [];
|
38
|
-
$scope.upload_count = 0;
|
39
|
-
|
40
|
-
|
41
|
-
//
|
42
|
-
// See Condo.Config for configuration options
|
43
|
-
//
|
44
|
-
$scope.endpoint = config.endpoint;
|
45
|
-
$scope.autostart = config.autostart;
|
46
|
-
$scope.ignore_errors = config.ignore_errors; // Continue to autostart after an error?
|
47
|
-
$scope.parallelism = config.parallelism; // number of uploads at once
|
48
|
-
|
49
|
-
|
50
|
-
$scope.add = function(files) {
|
51
|
-
var length = files.length,
|
52
|
-
i = 0,
|
53
|
-
ret = 0, // We only want to check for auto-start after the files have been added
|
54
|
-
file;
|
55
|
-
|
56
|
-
for (; i < length; i += 1) {
|
57
|
-
file = files[i];
|
58
|
-
|
59
|
-
if(file.size <= 0 || file.type == '')
|
60
|
-
continue;
|
61
|
-
|
62
|
-
//
|
63
|
-
// check file size is acceptable
|
64
|
-
//
|
65
|
-
if(!config.file_checker(file) || (config.size_limit != undefined && file.size > config.size_limit)) {
|
66
|
-
broadcaster.broadcast('coNotice', {
|
67
|
-
type: 'warn',
|
68
|
-
number: 0,
|
69
|
-
file: file
|
70
|
-
});
|
71
|
-
continue;
|
72
|
-
}
|
73
|
-
|
74
|
-
$scope.upload_count += 1;
|
75
|
-
|
76
|
-
api.check_provider($scope.endpoint, files[i]).then(function(upload){
|
77
|
-
ret += 1;
|
78
|
-
$scope.uploads.push(upload);
|
79
|
-
if(ret == length)
|
80
|
-
$scope.check_autostart();
|
81
|
-
}, function(failure) {
|
82
|
-
|
83
|
-
$scope.upload_count -= 1;
|
84
|
-
|
85
|
-
ret += 1;
|
86
|
-
if(ret == length)
|
87
|
-
$scope.check_autostart();
|
88
|
-
|
89
|
-
//
|
90
|
-
// broadcast this so it can be handled by a directive
|
91
|
-
//
|
92
|
-
broadcaster.broadcast('coNotice', failure);
|
93
|
-
});
|
94
|
-
}
|
95
|
-
};
|
96
|
-
|
97
|
-
|
98
|
-
$scope.abort = function(upload) {
|
99
|
-
upload.abort();
|
100
|
-
$scope.check_autostart();
|
101
|
-
};
|
102
|
-
|
103
|
-
|
104
|
-
$scope.remove = function(upload) {
|
105
|
-
//
|
106
|
-
// Splice(upload, 1) was unreliable. This is better
|
107
|
-
//
|
108
|
-
for (var i = 0, length = $scope.uploads.length; i < length; i += 1) {
|
109
|
-
if($scope.uploads[i] === upload) {
|
110
|
-
$scope.uploads.splice(i, 1);
|
111
|
-
$scope.upload_count -= 1;
|
112
|
-
break;
|
113
|
-
}
|
114
|
-
}
|
115
|
-
};
|
116
|
-
|
117
|
-
|
118
|
-
$scope.playpause = function(upload) {
|
119
|
-
if (upload.state == 3) // Uploading
|
120
|
-
upload.pause();
|
121
|
-
else
|
122
|
-
upload.start();
|
123
|
-
};
|
124
|
-
|
125
|
-
|
126
|
-
//
|
127
|
-
// Watch autostart and trigger a check when it is changed
|
128
|
-
//
|
129
|
-
$scope.$watch('autostart', function(newValue, oldValue) {
|
130
|
-
if (newValue === true)
|
131
|
-
$scope.check_autostart();
|
132
|
-
});
|
133
|
-
|
134
|
-
|
135
|
-
//
|
136
|
-
// Autostart more uploads as this is bumped up
|
137
|
-
//
|
138
|
-
$scope.$watch('parallelism', function(newValue, oldValue) {
|
139
|
-
if(newValue > oldValue)
|
140
|
-
$scope.check_autostart();
|
141
|
-
});
|
142
|
-
|
143
|
-
|
144
|
-
$scope.check_autostart = function() {
|
145
|
-
//
|
146
|
-
// Check if any uploads have been started already
|
147
|
-
// If there are no active uploads we'll auto-start
|
148
|
-
//
|
149
|
-
// PENDING = 0,
|
150
|
-
// STARTED = 1,
|
151
|
-
// PAUSED = 2,
|
152
|
-
// UPLOADING = 3,
|
153
|
-
// COMPLETED = 4,
|
154
|
-
// ABORTED = 5
|
155
|
-
//
|
156
|
-
if ($scope.autostart) {
|
157
|
-
var shouldStart = true,
|
158
|
-
state, i, length, started = 0;
|
159
|
-
|
160
|
-
for (i = 0, length = $scope.uploads.length; i < length; i += 1) {
|
161
|
-
state = $scope.uploads[i].state;
|
162
|
-
|
163
|
-
//
|
164
|
-
// Count started uploads (that don't have errors if we are ignoring errors)
|
165
|
-
// Up until we've reached our parallel limit, then stop
|
166
|
-
//
|
167
|
-
if (state > 0 && state < 4 && !($scope.uploads[i].error && $scope.ignore_errors)) {
|
168
|
-
started += 1;
|
169
|
-
if(started >= $scope.parallelism) {
|
170
|
-
shouldStart = false;
|
171
|
-
break;
|
172
|
-
}
|
173
|
-
}
|
174
|
-
}
|
175
|
-
|
176
|
-
if (shouldStart) {
|
177
|
-
started = $scope.parallelism - started; // How many can we start
|
178
|
-
|
179
|
-
for (i = 0; i < length; i += 1) {
|
180
|
-
if ($scope.uploads[i].state == 0) {
|
181
|
-
$scope.uploads[i].start();
|
182
|
-
|
183
|
-
started -= 1;
|
184
|
-
if(started <= 0) // Break if we can't start anymore
|
185
|
-
break;
|
186
|
-
}
|
187
|
-
}
|
188
|
-
}
|
189
|
-
}
|
190
|
-
};
|
191
|
-
|
192
|
-
}]);
|
193
|
-
|
194
|
-
}));
|
@@ -1,310 +0,0 @@
|
|
1
|
-
/**
|
2
|
-
* CoTag Condo
|
3
|
-
* Direct to cloud resumable uploads
|
4
|
-
*
|
5
|
-
* Copyright (c) 2012 CoTag Media.
|
6
|
-
*
|
7
|
-
* @author Stephen von Takach <steve@cotag.me>
|
8
|
-
* @copyright 2012 cotag.me
|
9
|
-
*
|
10
|
-
*
|
11
|
-
* References:
|
12
|
-
* * https://github.com/umdjs/umd
|
13
|
-
* * https://github.com/addyosmani/jquery-plugin-patterns
|
14
|
-
* * http://docs.angularjs.org/api/ng.$http
|
15
|
-
* * http://docs.angularjs.org/api/ng.$q
|
16
|
-
*
|
17
|
-
**/
|
18
|
-
|
19
|
-
(function (factory) {
|
20
|
-
if (typeof define === 'function' && define.amd) {
|
21
|
-
// AMD
|
22
|
-
define('condo-uploader', ['jquery', 'condo-broadcaster'], factory);
|
23
|
-
} else {
|
24
|
-
// Browser globals
|
25
|
-
window.CondoUploader = factory(jQuery);
|
26
|
-
}
|
27
|
-
}(function ($) {
|
28
|
-
'use strict';
|
29
|
-
|
30
|
-
var uploads = angular.module('CondoUploader', ['CondoBroadcaster']),
|
31
|
-
residencies = {};
|
32
|
-
|
33
|
-
|
34
|
-
//
|
35
|
-
// Implements the Condo API
|
36
|
-
//
|
37
|
-
uploads.factory('Condo.Api', ['$http', '$rootScope', '$q', function($http, $rootScope, $q) {
|
38
|
-
|
39
|
-
|
40
|
-
var token = $('meta[name="csrf-token"]').attr('content'),
|
41
|
-
|
42
|
-
|
43
|
-
condoConnection = function(api_endpoint, params) {
|
44
|
-
this.endpoint = api_endpoint; // The API mounting point
|
45
|
-
this.params = params; // Custom API parameters
|
46
|
-
|
47
|
-
this.upload_id = null; // The current upload ID
|
48
|
-
this.aborting = false; // Has the user has requested an abort?
|
49
|
-
this.xhr = null; // Any active cloud file xhr requests
|
50
|
-
};
|
51
|
-
|
52
|
-
|
53
|
-
$http.defaults.headers = {};
|
54
|
-
$http.defaults.headers['common'] = {'X-Requested-With': 'XMLHttpRequest'};
|
55
|
-
$http.defaults.headers['post'] = {'X-CSRF-Token': token};
|
56
|
-
$http.defaults.headers['put'] = {'X-CSRF-Token': token};
|
57
|
-
$http.defaults.headers['delete'] = {'X-CSRF-Token': token};
|
58
|
-
|
59
|
-
condoConnection.prototype = {
|
60
|
-
|
61
|
-
|
62
|
-
//
|
63
|
-
// Creates an entry in the database for the requested file and returns the upload signature
|
64
|
-
// If an entry already exists it returns a parts request signature for resumable uploads
|
65
|
-
//
|
66
|
-
create: function(options) { // file_id: 123, options: {}
|
67
|
-
var self = this;
|
68
|
-
options = options || {};
|
69
|
-
this.aborting = false;
|
70
|
-
|
71
|
-
if(!!options['file_id'])
|
72
|
-
this.params['file_id'] = options['file_id'];
|
73
|
-
|
74
|
-
if(!!options['parameters'])
|
75
|
-
this.params['parameters'] = options['parameters']; // We may be requesting the next set of parts
|
76
|
-
|
77
|
-
return $http({
|
78
|
-
method: 'POST',
|
79
|
-
url: this.endpoint,
|
80
|
-
params: this.params
|
81
|
-
}).then(function(result){
|
82
|
-
result = result.data;
|
83
|
-
self.upload_id = result.upload_id; // Extract the upload id from the results
|
84
|
-
|
85
|
-
if (!self.aborting)
|
86
|
-
return result;
|
87
|
-
else
|
88
|
-
return $q.reject(undefined);
|
89
|
-
}, function(reason) {
|
90
|
-
return $q.reject('upload error');
|
91
|
-
});
|
92
|
-
},
|
93
|
-
|
94
|
-
|
95
|
-
//
|
96
|
-
// This requests a chunk signature
|
97
|
-
// Only used for resumable uploads
|
98
|
-
//
|
99
|
-
edit: function(part_number, part_id) {
|
100
|
-
var self = this;
|
101
|
-
this.aborting = false;
|
102
|
-
|
103
|
-
return $http({
|
104
|
-
method: 'GET',
|
105
|
-
url: this.endpoint + '/' + this.upload_id + '/edit',
|
106
|
-
params: {
|
107
|
-
part: part_number,
|
108
|
-
file_id: part_id
|
109
|
-
}
|
110
|
-
}).then(function(result){
|
111
|
-
if (!self.aborting)
|
112
|
-
return result.data;
|
113
|
-
else
|
114
|
-
return $q.reject(undefined);
|
115
|
-
}, function(reason) {
|
116
|
-
return $q.reject('upload error');
|
117
|
-
});
|
118
|
-
},
|
119
|
-
|
120
|
-
|
121
|
-
//
|
122
|
-
// If resumable id is present the upload is updated
|
123
|
-
// Otherwise the upload deemed complete
|
124
|
-
//
|
125
|
-
update: function(params) { // optional parameters (resumable_id, file_id and part)
|
126
|
-
var self = this;
|
127
|
-
|
128
|
-
this.aborting = false;
|
129
|
-
params = params || {};
|
130
|
-
|
131
|
-
return $http({
|
132
|
-
method: 'PUT',
|
133
|
-
url: this.endpoint + '/' + this.upload_id,
|
134
|
-
params: params
|
135
|
-
}).then(function(result){
|
136
|
-
if (!self.aborting)
|
137
|
-
return result.data;
|
138
|
-
else
|
139
|
-
return $q.reject(undefined);
|
140
|
-
}, function(reason) {
|
141
|
-
if (reason.status == 401 && params.resumable_id == undefined) {
|
142
|
-
return ''; // User may have paused upload as put was being sent. We should let this through just to update the UI
|
143
|
-
} else
|
144
|
-
return $q.reject('upload error');
|
145
|
-
});
|
146
|
-
},
|
147
|
-
|
148
|
-
|
149
|
-
//
|
150
|
-
// Cancels a resumable upload
|
151
|
-
// The actual destruction of the file is handled on the server side as we can't trust the client to do this
|
152
|
-
// We don't care if this succeeds as the back-end will destroy the file eventually anyway.
|
153
|
-
//
|
154
|
-
destroy: function() {
|
155
|
-
return $http({
|
156
|
-
method: 'DELETE',
|
157
|
-
url: this.endpoint + '/' + this.upload_id
|
158
|
-
});
|
159
|
-
},
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
//
|
164
|
-
// Provides a promise for any request this is what communicated with the cloud storage servers
|
165
|
-
//
|
166
|
-
process_request: function(signature, progress_callback) {
|
167
|
-
var self = this,
|
168
|
-
result = $q.defer(),
|
169
|
-
params = {
|
170
|
-
url: signature.signature.url,
|
171
|
-
type: signature.signature.verb,
|
172
|
-
headers: signature.signature.headers,
|
173
|
-
processData: false,
|
174
|
-
success: function(response, textStatus, jqXHR) {
|
175
|
-
self.xhr = null;
|
176
|
-
result.resolve(response);
|
177
|
-
},
|
178
|
-
error: function(jqXHR, textStatus, errorThrown) {
|
179
|
-
self.xhr = null;
|
180
|
-
if (!self.aborting)
|
181
|
-
result.reject('upload error');
|
182
|
-
else
|
183
|
-
result.reject(undefined);
|
184
|
-
},
|
185
|
-
complete: function(jqXHR, textStatus) {
|
186
|
-
if(!$rootScope.$$phase) {
|
187
|
-
$rootScope.$apply(); // This triggers the promise response
|
188
|
-
}
|
189
|
-
}
|
190
|
-
};
|
191
|
-
|
192
|
-
this.aborting = false;
|
193
|
-
|
194
|
-
if (!!self.xhr) {
|
195
|
-
result.reject('request in progress'); // This is awesome
|
196
|
-
return result.promise;
|
197
|
-
}
|
198
|
-
|
199
|
-
if(!!signature.data){
|
200
|
-
params['data'] = signature.data;
|
201
|
-
}
|
202
|
-
|
203
|
-
if(!!progress_callback) {
|
204
|
-
params['xhr'] = function() {
|
205
|
-
var xhr = $.ajaxSettings.xhr();
|
206
|
-
if(!!xhr.upload){
|
207
|
-
xhr.upload.addEventListener('progress', function(e) {
|
208
|
-
if (e.lengthComputable) {
|
209
|
-
var phase = $rootScope.$$phase;
|
210
|
-
if(phase == '$apply' || phase == '$digest') {
|
211
|
-
progress_callback(e.loaded);
|
212
|
-
} else {
|
213
|
-
$rootScope.$apply(function(){
|
214
|
-
progress_callback(e.loaded);
|
215
|
-
});
|
216
|
-
}
|
217
|
-
}
|
218
|
-
}, false);
|
219
|
-
}
|
220
|
-
return xhr;
|
221
|
-
};
|
222
|
-
}
|
223
|
-
|
224
|
-
this.xhr = $.ajax(params);
|
225
|
-
|
226
|
-
return result.promise;
|
227
|
-
},
|
228
|
-
|
229
|
-
|
230
|
-
//
|
231
|
-
// Will trigger the error call-back of the xhr object
|
232
|
-
//
|
233
|
-
abort: function() {
|
234
|
-
this.aborting = true;
|
235
|
-
if(!!this.xhr) {
|
236
|
-
this.xhr.abort();
|
237
|
-
}
|
238
|
-
}
|
239
|
-
};
|
240
|
-
|
241
|
-
return {
|
242
|
-
//
|
243
|
-
// Used to determine what upload strategy to use (Amazon, Google, etc)
|
244
|
-
//
|
245
|
-
check_provider: function(api_endpoint, the_file, params) {
|
246
|
-
params = params || {};
|
247
|
-
params['file_size'] = the_file.size;
|
248
|
-
params['file_name'] = the_file.name;
|
249
|
-
|
250
|
-
if(!!the_file.dir_path)
|
251
|
-
params['file_path'] = the_file.dir_path;
|
252
|
-
|
253
|
-
return $http({
|
254
|
-
method: 'GET',
|
255
|
-
url: api_endpoint + '/new',
|
256
|
-
params: params
|
257
|
-
}).then(function(result){
|
258
|
-
if(!!residencies[result.data.residence]) {
|
259
|
-
|
260
|
-
var api = new condoConnection(api_endpoint, params);
|
261
|
-
|
262
|
-
//
|
263
|
-
// TODO:: Check if a file is already in the list and reject if it is
|
264
|
-
//
|
265
|
-
return residencies[result.data.residence].new_upload(api, the_file); // return the instantiated provider
|
266
|
-
|
267
|
-
} else {
|
268
|
-
return $q.reject({
|
269
|
-
type: 'error',
|
270
|
-
number: 0,
|
271
|
-
file: the_file
|
272
|
-
});
|
273
|
-
}
|
274
|
-
}, function(reason) {
|
275
|
-
if(reason.status == 406) {
|
276
|
-
return $q.reject({
|
277
|
-
type: 'warn',
|
278
|
-
number: 0,
|
279
|
-
details: reason.data,
|
280
|
-
file: the_file
|
281
|
-
});
|
282
|
-
} else {
|
283
|
-
return $q.reject({
|
284
|
-
type: 'warn',
|
285
|
-
number: 1,
|
286
|
-
file: the_file
|
287
|
-
});
|
288
|
-
}
|
289
|
-
});
|
290
|
-
}
|
291
|
-
};
|
292
|
-
}]).factory('Condo.Registrar', function(){
|
293
|
-
return {
|
294
|
-
//
|
295
|
-
// Simple dependency injection allows us to load only the providers we need
|
296
|
-
//
|
297
|
-
register: function(provider_name, iface) {
|
298
|
-
residencies[provider_name] = iface;
|
299
|
-
}
|
300
|
-
};
|
301
|
-
});
|
302
|
-
|
303
|
-
|
304
|
-
|
305
|
-
//
|
306
|
-
// Anonymous function return
|
307
|
-
//
|
308
|
-
return uploads;
|
309
|
-
|
310
|
-
}));
|