condo 1.0.4 → 1.0.6
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/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
|
-
}));
|