condo 1.0.6 → 2.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.
Files changed (60) hide show
  1. checksums.yaml +4 -4
  2. data/README.textile +19 -32
  3. data/lib/condo.rb +124 -127
  4. data/lib/condo/configuration.rb +41 -76
  5. data/lib/condo/engine.rb +32 -39
  6. data/lib/condo/errors.rb +6 -8
  7. data/lib/condo/strata/amazon_s3.rb +246 -294
  8. data/lib/condo/strata/google_cloud_storage.rb +238 -272
  9. data/lib/condo/strata/open_stack_swift.rb +251 -0
  10. data/lib/condo/version.rb +1 -1
  11. metadata +31 -96
  12. data/app/assets/javascripts/condo.js +0 -9
  13. data/app/assets/javascripts/condo/amazon.js +0 -403
  14. data/app/assets/javascripts/condo/condo.js +0 -184
  15. data/app/assets/javascripts/condo/config.js +0 -69
  16. data/app/assets/javascripts/condo/google.js +0 -338
  17. data/app/assets/javascripts/condo/md5/hash.worker.emulator.js +0 -23
  18. data/app/assets/javascripts/condo/md5/hash.worker.js +0 -11
  19. data/app/assets/javascripts/condo/md5/hasher.js +0 -119
  20. data/app/assets/javascripts/condo/md5/spark-md5.js +0 -599
  21. data/app/assets/javascripts/condo/rackspace.js +0 -326
  22. data/app/assets/javascripts/condo/services/abstract-md5.js.erb +0 -86
  23. data/app/assets/javascripts/condo/services/base64.js +0 -184
  24. data/app/assets/javascripts/condo/services/broadcaster.js +0 -26
  25. data/app/assets/javascripts/condo/services/uploader.js +0 -302
  26. data/app/assets/javascripts/core/core.js +0 -4
  27. data/app/assets/javascripts/core/services/1-safe-apply.js +0 -17
  28. data/app/assets/javascripts/core/services/2-messaging.js +0 -171
  29. data/lib/condo/strata/rackspace_cloud_files.rb +0 -245
  30. data/test/condo_test.rb +0 -27
  31. data/test/dummy/README.rdoc +0 -261
  32. data/test/dummy/Rakefile +0 -7
  33. data/test/dummy/app/assets/javascripts/application.js +0 -15
  34. data/test/dummy/app/assets/stylesheets/application.css +0 -13
  35. data/test/dummy/app/controllers/application_controller.rb +0 -3
  36. data/test/dummy/app/helpers/application_helper.rb +0 -2
  37. data/test/dummy/app/views/layouts/application.html.erb +0 -14
  38. data/test/dummy/config.ru +0 -4
  39. data/test/dummy/config/application.rb +0 -59
  40. data/test/dummy/config/boot.rb +0 -10
  41. data/test/dummy/config/database.yml +0 -25
  42. data/test/dummy/config/environment.rb +0 -5
  43. data/test/dummy/config/environments/development.rb +0 -37
  44. data/test/dummy/config/environments/production.rb +0 -67
  45. data/test/dummy/config/environments/test.rb +0 -37
  46. data/test/dummy/config/initializers/backtrace_silencers.rb +0 -7
  47. data/test/dummy/config/initializers/inflections.rb +0 -15
  48. data/test/dummy/config/initializers/mime_types.rb +0 -5
  49. data/test/dummy/config/initializers/secret_token.rb +0 -7
  50. data/test/dummy/config/initializers/session_store.rb +0 -8
  51. data/test/dummy/config/initializers/wrap_parameters.rb +0 -14
  52. data/test/dummy/config/locales/en.yml +0 -5
  53. data/test/dummy/config/routes.rb +0 -58
  54. data/test/dummy/public/404.html +0 -26
  55. data/test/dummy/public/422.html +0 -26
  56. data/test/dummy/public/500.html +0 -25
  57. data/test/dummy/public/favicon.ico +0 -0
  58. data/test/dummy/script/rails +0 -6
  59. data/test/integration/navigation_test.rb +0 -10
  60. data/test/test_helper.rb +0 -15
@@ -1,26 +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
- * *
13
- *
14
- **/
15
-
16
-
17
- (function(angular, undefined) {
18
- 'use strict';
19
-
20
- angular.module('Condo').
21
-
22
- factory('Condo.Broadcast', ['$channel', function($channel) {
23
- return $channel.openChannel('once unique');
24
- }]);
25
-
26
- })(angular);
@@ -1,302 +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
- * * http://docs.angularjs.org/api/ng.$http
13
- * * http://docs.angularjs.org/api/ng.$q
14
- *
15
- **/
16
-
17
-
18
- (function(jQuery, angular, undefined) { // jQuery required for progress event
19
- 'use strict';
20
-
21
- angular.module('Condo').
22
-
23
- //
24
- // Implements the Condo API
25
- //
26
- provider('Condo.Api', function() {
27
-
28
- var residencies = {};
29
-
30
- this.register = function(provider_name, dependency) {
31
- residencies[provider_name] = dependency;
32
- };
33
-
34
-
35
- this.$get = ['$http', '$rootScope', '$q', '$injector', function($http, $rootScope, $q, $injector) {
36
- var token = $('meta[name="csrf-token"]').attr('content'),
37
-
38
-
39
- condoConnection = function(api_endpoint, params) {
40
- this.endpoint = api_endpoint; // The API mounting point
41
- this.params = params; // Custom API parameters
42
-
43
- this.upload_id = null; // The current upload ID
44
- this.aborting = false; // Has the user has requested an abort?
45
- this.xhr = null; // Any active cloud file xhr requests
46
- };
47
-
48
-
49
- // Inject the handlers
50
- angular.forEach(residencies, function(value, key) {
51
- residencies[key] = $injector.get(value);
52
- });
53
-
54
-
55
- $http.defaults.headers = {};
56
- $http.defaults.headers['common'] = {'X-Requested-With': 'XMLHttpRequest'};
57
- $http.defaults.headers['post'] = {'X-CSRF-Token': token};
58
- $http.defaults.headers['put'] = {'X-CSRF-Token': token};
59
- $http.defaults.headers['delete'] = {'X-CSRF-Token': token};
60
-
61
- condoConnection.prototype = {
62
-
63
-
64
- //
65
- // Creates an entry in the database for the requested file and returns the upload signature
66
- // If an entry already exists it returns a parts request signature for resumable uploads
67
- //
68
- create: function(options) { // file_id: 123, options: {}
69
- var self = this;
70
- options = options || {};
71
- this.aborting = false;
72
-
73
- if(!!options['file_id'])
74
- this.params['file_id'] = options['file_id'];
75
-
76
- if(!!options['parameters'])
77
- this.params['parameters'] = options['parameters']; // We may be requesting the next set of parts
78
-
79
- return $http({
80
- method: 'POST',
81
- url: this.endpoint,
82
- params: this.params
83
- }).then(function(result){
84
- result = result.data;
85
- self.upload_id = result.upload_id; // Extract the upload id from the results
86
-
87
- if (!self.aborting)
88
- return result;
89
- else
90
- return $q.reject(undefined);
91
- }, function(reason) {
92
- return $q.reject('upload error');
93
- });
94
- },
95
-
96
-
97
- //
98
- // This requests a chunk signature
99
- // Only used for resumable uploads
100
- //
101
- edit: function(part_number, part_id) {
102
- var self = this;
103
- this.aborting = false;
104
-
105
- return $http({
106
- method: 'GET',
107
- url: this.endpoint + '/' + this.upload_id + '/edit',
108
- params: {
109
- part: part_number,
110
- file_id: part_id
111
- }
112
- }).then(function(result){
113
- if (!self.aborting)
114
- return result.data;
115
- else
116
- return $q.reject(undefined);
117
- }, function(reason) {
118
- return $q.reject('upload error');
119
- });
120
- },
121
-
122
-
123
- //
124
- // If resumable id is present the upload is updated
125
- // Otherwise the upload deemed complete
126
- //
127
- update: function(params) { // optional parameters (resumable_id, file_id and part)
128
- var self = this;
129
-
130
- this.aborting = false;
131
- params = params || {};
132
-
133
- return $http({
134
- method: 'PUT',
135
- url: this.endpoint + '/' + this.upload_id,
136
- params: params
137
- }).then(function(result){
138
- if (!self.aborting)
139
- return result.data;
140
- else
141
- return $q.reject(undefined);
142
- }, function(reason) {
143
- if (reason.status == 401 && params.resumable_id == undefined) {
144
- return ''; // User may have paused upload as put was being sent. We should let this through just to update the UI
145
- } else
146
- return $q.reject('upload error');
147
- });
148
- },
149
-
150
-
151
- //
152
- // Cancels a resumable upload
153
- // The actual destruction of the file is handled on the server side as we can't trust the client to do this
154
- // We don't care if this succeeds as the back-end will destroy the file eventually anyway.
155
- //
156
- destroy: function() {
157
- return $http({
158
- method: 'DELETE',
159
- url: this.endpoint + '/' + this.upload_id
160
- });
161
- },
162
-
163
-
164
-
165
- //
166
- // Provides a promise for any request this is what communicated with the cloud storage servers
167
- //
168
- process_request: function(signature, progress_callback) {
169
- var self = this,
170
- result = $q.defer(),
171
- params = {
172
- url: signature.signature.url,
173
- type: signature.signature.verb,
174
- headers: signature.signature.headers,
175
- processData: false,
176
- success: function(response, textStatus, jqXHR) {
177
- self.xhr = null;
178
- result.resolve([response, jqXHR]);
179
- },
180
- error: function(jqXHR, textStatus, errorThrown) {
181
- if(jqXHR.status === signature.expected) {
182
- self.xhr = null;
183
- result.resolve([errorThrown, jqXHR]);
184
- } else {
185
- self.xhr = null;
186
- if (!self.aborting)
187
- result.reject('upload error');
188
- else
189
- result.reject(undefined);
190
- }
191
- },
192
- complete: function(jqXHR, textStatus) {
193
- if(!$rootScope.$$phase) {
194
- $rootScope.$apply(); // This triggers the promise response
195
- }
196
- }
197
- };
198
-
199
- this.aborting = false;
200
-
201
- if (!!self.xhr) {
202
- result.reject('request in progress'); // This is awesome
203
- return result.promise;
204
- }
205
-
206
- if(!!signature.data){
207
- params['data'] = signature.data;
208
- }
209
-
210
- if(!!progress_callback) {
211
- params['xhr'] = function() {
212
- var xhr = jQuery.ajaxSettings.xhr();
213
- if(!!xhr.upload){
214
- xhr.upload.addEventListener('progress', function(e) {
215
- if (e.lengthComputable) {
216
- var phase = $rootScope.$$phase;
217
- if(phase == '$apply' || phase == '$digest') {
218
- progress_callback(e.loaded);
219
- } else {
220
- $rootScope.$apply(function(){
221
- progress_callback(e.loaded);
222
- });
223
- }
224
- }
225
- }, false);
226
- }
227
- return xhr;
228
- };
229
- }
230
-
231
- this.xhr = jQuery.ajax(params);
232
-
233
- return result.promise;
234
- },
235
-
236
-
237
- //
238
- // Will trigger the error call-back of the xhr object
239
- //
240
- abort: function() {
241
- this.aborting = true;
242
- if(!!this.xhr) {
243
- this.xhr.abort();
244
- }
245
- }
246
- };
247
-
248
- return {
249
- //
250
- // Used to determine what upload strategy to use (Amazon, Google, etc)
251
- //
252
- check_provider: function(api_endpoint, the_file, params) {
253
- params = params || {};
254
- params['file_size'] = the_file.size;
255
- params['file_name'] = the_file.name;
256
-
257
- if(!!the_file.dir_path)
258
- params['file_path'] = the_file.dir_path;
259
-
260
- return $http({
261
- method: 'GET',
262
- url: api_endpoint + '/new',
263
- params: params
264
- }).then(function(result){
265
- if(!!residencies[result.data.residence]) {
266
-
267
- var api = new condoConnection(api_endpoint, params);
268
-
269
- //
270
- // TODO:: Check if a file is already in the list and reject if it is
271
- //
272
- return residencies[result.data.residence].new_upload(api, the_file); // return the instantiated provider
273
-
274
- } else {
275
- return $q.reject({
276
- type: 'error',
277
- number: 0,
278
- file: the_file
279
- });
280
- }
281
- }, function(reason) {
282
- if(reason.status == 406) {
283
- return $q.reject({
284
- type: 'warn',
285
- number: 0,
286
- details: reason.data,
287
- file: the_file
288
- });
289
- } else {
290
- return $q.reject({
291
- type: 'warn',
292
- number: 1,
293
- file: the_file
294
- });
295
- }
296
- });
297
- }
298
- };
299
- }];
300
- });
301
-
302
- })(jQuery, angular);
@@ -1,4 +0,0 @@
1
- //
2
- // Defines our core module
3
- //
4
- angular.module('Core', []);
@@ -1,17 +0,0 @@
1
-
2
- (function(angular, undefined) {
3
- 'use strict';
4
-
5
- angular.module('Core').
6
- service('$safeApply', function() {
7
- this.do = function(scope, fn) {
8
- var phase = scope.$root.$$phase;
9
- if(phase == '$apply' || phase == '$digest') {
10
- fn();
11
- } else {
12
- scope.$apply(fn);
13
- }
14
- };
15
- });
16
-
17
- })(angular);
@@ -1,171 +0,0 @@
1
- /**
2
- * Core Messaging library
3
- * Provides the core wrapper for application wide messaging and signalling
4
- *
5
- * Copyright (c) 2013 CoTag Media.
6
- *
7
- * @author Stephen von Takach <steve@cotag.me>
8
- * @copyright 2013 cotag.me
9
- *
10
- *
11
- * References:
12
- * * http://www.gridlinked.info/angularJS/modules/MessagingServices.js
13
- *
14
- *
15
- **/
16
-
17
- (function(angular, undefined) {
18
- 'use strict';
19
-
20
- angular.module('Core').
21
- //
22
- //
23
- // Wrapper for jQuery Callbacks that provides a constructor for building
24
- // application specific message channels
25
- //
26
- // e.g.
27
- // factory('MyApp.Channel', ['Channel', function(Channel) {
28
- // return Channel.openChannel('once memory unique stopOnFalse'); // settings are optional
29
- // }]);
30
- //
31
- // then in a controller / directive somewhere:
32
- // controller('MyApp.Cntrl', ['$scope', 'MyApp.Channel', function($scope, channel) {
33
- // channel.subscribe(function(value) { $scope.update = value; });
34
- // }
35
- //
36
- //
37
- factory('$channel', ['$rootScope', '$safeApply', function($rootScope, safeApply) {
38
- var getChannel = function(settings) {
39
- var callback = angular.element.Callbacks(settings);
40
- return {
41
- publish: function() {
42
- var args = arguments; // Curry the arguments
43
- safeApply.do($rootScope, function() {
44
- callback.fire.apply(callback, args);
45
- });
46
- },
47
- subscribe: callback.add,
48
- unsubscribe: callback.remove,
49
- has: callback.has,
50
- empty: callback.empty
51
- };
52
- };
53
-
54
- return {
55
- openChannel: getChannel
56
- };
57
- }]).
58
-
59
-
60
- //
61
- //
62
- // Wrapper for jQuery Callbacks that provides a constructor for building
63
- // application specific messaging factories
64
- //
65
- // e.g.
66
- // factory('MyApp.Messenger', ['Spectrum', function(Spectrum) {
67
- // return Spectrum.newSpectrum('once memory unique stopOnFalse'); // settings are optional
68
- // }]);
69
- //
70
- // then in a controller / directive somewhere:
71
- // controller('MyApp.Cntrl', ['$scope', 'MyApp.Messenger', function($scope, messages) {
72
- // var channel = messages.openChannel('controllers');
73
- // channel.subscribe(function(value) { $scope.update = value; });
74
- // }
75
- //
76
- //
77
- factory('$spectrum', ['$channel', function(Channel) {
78
-
79
- var buildSpectrum = function(settings) {
80
- var channels = {},
81
-
82
- //
83
- // Creates or returns a reference to a channel in the spectrum
84
- //
85
- openChannel = function(name) {
86
- var channel = name && channels[name],
87
- callback;
88
-
89
- if (!channel) {
90
- channel = {
91
- access: Channel.openChannel(settings),
92
- count: 0
93
- };
94
-
95
- channels[name] = channel;
96
- }
97
-
98
- return channel;
99
- }, // end openChannel
100
-
101
- //
102
- // Deletes channels that are no longer in use
103
- //
104
- closeChannel = function(name) {
105
- delete channels[name];
106
- return 0;
107
- },
108
-
109
- channelList = function() {
110
- return Object.keys(channels);
111
- },
112
-
113
- subscribeTo = function(name, callback) {
114
- var channel = channels[name] || openChannel(name);
115
- if(!channel.access.has(callback)) {
116
- channel.access.subscribe(callback);
117
- channel.count += 1;
118
- }
119
- return channel.count;
120
- },
121
-
122
- subscribedTo = function(name) {
123
- return !channels[name] ? 0 : channels[name].count;
124
- },
125
-
126
- unsubscribeFrom = function(name, callback) {
127
- var channel = channels[name];
128
-
129
- if (!!channel) {
130
- if(callback === undefined) {
131
- return closeChannel(name);
132
- } else if (channel.access.has(callback)) {
133
- if (channel.count > 1) {
134
- channel.access.unsubscribe(callback);
135
- channel.count -= 1;
136
- } else {
137
- return closeChannel(name);
138
- }
139
- }
140
- return channel.count;
141
- }
142
- return 0;
143
- },
144
-
145
- publishTo = function(name) {
146
- var channel = channels[name];
147
-
148
- if (!!channel) {
149
- channel.access.publish.apply(channel.access, Array.prototype.slice.call( arguments, 1 ));
150
- } else if (settings.match(/memory/i)) {
151
- channel = openChannel(name);
152
- channel.access.publish.apply(channel.access, Array.prototype.slice.call( arguments, 1 ));
153
- }
154
- };
155
-
156
- return {
157
- channelList: channelList,
158
- subscribe: subscribeTo,
159
- subscriptions: subscribedTo,
160
- unsubscribe: unsubscribeFrom,
161
- publish: publishTo
162
- };
163
- }; // End buildSpectrum
164
-
165
- return {
166
- newSpectrum: buildSpectrum
167
- };
168
- }]);
169
-
170
-
171
- })(angular);