adapter.js 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375
  1. /**
  2. * Licensed to the Apache Software Foundation (ASF) under one
  3. * or more contributor license agreements. See the NOTICE file
  4. * distributed with this work for additional information
  5. * regarding copyright ownership. The ASF licenses this file
  6. * to you under the Apache License, Version 2.0 (the
  7. * "License"); you may not use this file except in compliance
  8. * with the License. You may obtain a copy of the License at
  9. *
  10. * http://www.apache.org/licenses/LICENSE-2.0
  11. *
  12. * Unless required by applicable law or agreed to in writing, software
  13. * distributed under the License is distributed on an "AS IS" BASIS,
  14. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  15. * See the License for the specific language governing permissions and
  16. * limitations under the License.
  17. */
  18. App = require('app');
  19. function promiseArray(promise, label) {
  20. return Ember.ArrayProxy.extend(Ember.PromiseProxyMixin).create({
  21. promise: Ember.RSVP.Promise.cast(promise, label)
  22. });
  23. }
  24. function serializerForAdapter(adapter, type) {
  25. var serializer = adapter.serializer,
  26. defaultSerializer = adapter.defaultSerializer,
  27. container = adapter.container;
  28. if (container && serializer === undefined) {
  29. serializer = serializerFor(container, type.typeKey, defaultSerializer);
  30. }
  31. if (serializer === null || serializer === undefined) {
  32. serializer = {
  33. extract: function(store, type, payload) { return payload; }
  34. };
  35. }
  36. return serializer;
  37. }
  38. function serializerFor(container, type, defaultSerializer) {
  39. return container.lookup('serializer:'+type) ||
  40. container.lookup('serializer:application') ||
  41. container.lookup('serializer:' + defaultSerializer) ||
  42. container.lookup('serializer:-default');
  43. }
  44. function _listdir(adapter, store, type, query, recordArray) {
  45. var promise = adapter.listdir(store, type, query, recordArray),
  46. serializer = serializerForAdapter(adapter, type),
  47. label = "";
  48. return Ember.RSVP.Promise.cast(promise, label).then(function(adapterPayload) {
  49. var payload = serializer.extractArray(store, type, adapterPayload);
  50. Ember.assert("The response from a findQuery must be an Array, not " + Ember.inspect(payload), Ember.typeOf(payload) === 'array');
  51. recordArray.load(payload);
  52. return recordArray;
  53. }, null, "DS: Extract payload of findQuery " + type);
  54. }
  55. function _move(adapter, store, record, query) {
  56. var type = store.modelFor('file'),
  57. promise = adapter.move(store, type, record, query),
  58. serializer = serializerForAdapter(adapter, type),
  59. label = "";
  60. return promise.then(function(adapterPayload) {
  61. var payload;
  62. if (adapterPayload) {
  63. payload = serializer.extractSingle(store, type, adapterPayload);
  64. } else {
  65. payload = adapterPayload;
  66. }
  67. //TODO very shady activity :/
  68. if (typeof record == 'object') {
  69. store.unloadRecord(record);
  70. }
  71. return store.push('file', payload);
  72. }, function(reason) {
  73. if (reason instanceof DS.InvalidError) {
  74. store.recordWasInvalid(record, reason.errors);
  75. } else {
  76. store.recordWasError(record, reason);
  77. }
  78. throw reason;
  79. }, label);
  80. }
  81. function _mkdir(adapter, store, type, query) {
  82. var promise = adapter.mkdir(store, type, query),
  83. serializer = serializerForAdapter(adapter, type),
  84. label = "";
  85. return promise.then(function(adapterPayload) {
  86. var payload;
  87. if (adapterPayload) {
  88. payload = serializer.extractSingle(store, type, adapterPayload);
  89. } else {
  90. payload = adapterPayload;
  91. }
  92. return store.push('file', payload);
  93. }, function(reason) {
  94. if (reason instanceof DS.InvalidError) {
  95. store.recordWasInvalid(record, reason.errors);
  96. } else {
  97. store.recordWasError(record, reason);
  98. }
  99. throw reason;
  100. }, label);
  101. }
  102. function _remove(adapter, store, record, query) {
  103. var type = record.constructor;
  104. var promise = adapter.remove(store, type, query),
  105. serializer = serializerForAdapter(adapter, type),
  106. label = "";
  107. return promise.then(function(adapterPayload) {
  108. store.unloadRecord(record);
  109. return record;
  110. }, function(reason) {
  111. if (reason instanceof DS.InvalidError) {
  112. store.recordWasInvalid(record, reason.errors);
  113. } else {
  114. store.recordWasError(record, reason);
  115. }
  116. throw reason;
  117. }, label);
  118. }
  119. Ember.Inflector.inflector.uncountable('fileops');
  120. Ember.Inflector.inflector.uncountable('download');
  121. Ember.Inflector.inflector.uncountable('upload');
  122. function getNamespaceUrl() {
  123. var parts = window.location.pathname.match(/\/[^\/]*/g);
  124. var view = parts[1];
  125. var version = '/versions' + parts[2];
  126. var instance = parts[3];
  127. if (parts.length == 4) { // version is not present
  128. instance = parts[2];
  129. version = '';
  130. }
  131. var namespaceUrl = 'api/v1/views' + view + version + '/instances' + instance + '/';
  132. return namespaceUrl;
  133. }
  134. App.Store = DS.Store.extend({
  135. adapter: DS.RESTAdapter.extend({
  136. namespace: getNamespaceUrl() + 'resources/files',
  137. headers: {
  138. 'X-Requested-By': 'ambari'
  139. },
  140. listdir: function(store, type, query) {
  141. return this.ajax(this.buildURL('fileops','listdir'), 'GET', { data: query });
  142. },
  143. move:function (store, type, record, query) {
  144. return this.ajax(this.buildURL('fileops','rename'), 'POST', { data: query });
  145. },
  146. mkdir:function (store, type, query) {
  147. return this.ajax(this.buildURL('fileops','mkdir'), 'PUT', { data: query });
  148. },
  149. remove:function (store, type, query) {
  150. return this.ajax(this.buildURL('fileops','remove'), 'DELETE', { data: query });
  151. },
  152. downloadUrl:function (option, query) {
  153. return [this.buildURL('download',option),Em.$.param(query)].join('?');
  154. },
  155. linkFor:function (option, query) {
  156. return this.ajax(this.buildURL('download',[option,'generate-link'].join('/')), 'POST', { data: query });
  157. }
  158. }),
  159. listdir:function (path) {
  160. var query = {path: path};
  161. var type = this.modelFor('file');
  162. var array = this.recordArrayManager
  163. .createAdapterPopulatedRecordArray(type, query);
  164. this.recordArrayManager.registerFilteredRecordArray(array, type);
  165. var adapter = this.adapterFor(type);
  166. Ember.assert("You tried to load a query but you have no adapter (for " + type + ")", adapter);
  167. Ember.assert("You tried to load a query but your adapter does not implement `listdir`", adapter.listdir);
  168. return promiseArray(_listdir(adapter, this, type, query, array));
  169. },
  170. move:function (record, path) {
  171. var oldpath;
  172. if (typeof record === 'string') {
  173. oldpath = record;
  174. } else {
  175. oldpath = record.get('id');
  176. }
  177. var query = {
  178. "src":oldpath,
  179. "dst":path
  180. };
  181. var promiseLabel = "DS: Model#move " + this;
  182. var resolver = Ember.RSVP.defer(promiseLabel);
  183. var adapter = this.adapterFor(record.constructor);
  184. resolver.resolve(_move(adapter, this, record, query));
  185. return DS.PromiseObject.create({ promise: resolver.promise });
  186. },
  187. mkdir:function (path) {
  188. var query = {
  189. "path":path
  190. };
  191. var type = this.modelFor('file');
  192. var promiseLabel = "DS: Model#mkdir " + this;
  193. var resolver = Ember.RSVP.defer(promiseLabel);
  194. var adapter = this.adapterFor(type);
  195. resolver.resolve(_mkdir(adapter, this, type, query));
  196. return DS.PromiseObject.create({ promise: resolver.promise });
  197. },
  198. remove:function (record) {
  199. var query = {
  200. "path":record.get('path'),
  201. "recursive":true
  202. };
  203. var type = this.modelFor('file');
  204. var promiseLabel = "DS: Model#remove " + this;
  205. var resolver = Ember.RSVP.defer(promiseLabel);
  206. var adapter = this.adapterFor(type);
  207. record.deleteRecord();
  208. resolver.resolve(_remove(adapter, this, record, query));
  209. return DS.PromiseObject.create({ promise: resolver.promise });
  210. },
  211. /**
  212. * get dowload link
  213. * @param {Array} file records for download
  214. * @param {String} option browse, zip or concat
  215. * @param {Boolean} download
  216. * @return {Promise}
  217. */
  218. linkFor:function (files, option, download) {
  219. var resolver = Ember.RSVP.defer('promiseLabel');
  220. var adapter = this.adapterFor(this.modelFor('file')),
  221. download = download || true;
  222. option = option || "browse";
  223. if (option == 'browse') {
  224. var query = { "path": files.get('firstObject.path'), "download": download };
  225. resolver.resolve(adapter.downloadUrl('browse',query))
  226. return resolver.promise;
  227. };
  228. var query = {
  229. "entries": [],
  230. "download": download
  231. };
  232. files.forEach(function (item) {
  233. query.entries.push(item.get('path'));
  234. });
  235. resolver.resolve(adapter.linkFor(option, query))
  236. return resolver.promise.then(function(response) {
  237. return adapter.downloadUrl(option,response);
  238. }, function(reason) {
  239. //TODO reject
  240. });
  241. }
  242. })
  243. App.FileSerializer = DS.RESTSerializer.extend({
  244. primaryKey:'path',
  245. extractArray: function(store, type, payload, id, requestType) {
  246. payload = {'files': payload};
  247. return this._super(store, type, payload, id, requestType);
  248. },
  249. extractSingle: function(store, type, payload, id, requestType) {
  250. payload = {'files': payload};
  251. return this._super(store, type, payload, id, requestType);
  252. }
  253. });
  254. App.Uploader = Ember.Uploader.create({
  255. url: '',
  256. type:'PUT',
  257. upload: function(file,extraData) {
  258. var data = this.setupFormData(file,extraData);
  259. var url = this.get('url');
  260. var type = this.get('type');
  261. var self = this;
  262. this.set('isUploading', true);
  263. return this.ajax(url, data, type).then(function(respData) {
  264. self.didUpload(respData);
  265. return respData;
  266. });
  267. },
  268. ajax: function(url, params, method) {
  269. var self = this;
  270. var settings = {
  271. url: url,
  272. type: method || 'POST',
  273. contentType: false,
  274. processData: false,
  275. xhr: function() {
  276. var xhr = Ember.$.ajaxSettings.xhr();
  277. xhr.upload.onprogress = function(e) {
  278. self.didProgress(e);
  279. };
  280. return xhr;
  281. },
  282. beforeSend:function (xhr) {
  283. xhr.setRequestHeader('X-Requested-By', 'ambari');
  284. },
  285. data: params
  286. };
  287. return this._ajax(settings);
  288. }
  289. });
  290. App.IsodateTransform = DS.Transform.extend({
  291. deserialize: function (serialized) {
  292. if (serialized) {
  293. return moment.utc(serialized).toDate();
  294. }
  295. return serialized;
  296. },
  297. serialize: function (deserialized) {
  298. if (deserialized) {
  299. return moment(deserialized).format('X');
  300. }
  301. return deserialized;
  302. }
  303. });
  304. Ember.Handlebars.registerBoundHelper('showDate', function(date,format) {
  305. return moment(date).format(format)
  306. });
  307. Ember.Handlebars.registerBoundHelper('showDateUnix', function(date,format) {
  308. return moment.unix(date).format(format)
  309. });
  310. Ember.Handlebars.registerBoundHelper('capitalize', function(string) {
  311. return string.capitalize();
  312. });
  313. Ember.Handlebars.registerBoundHelper('humanSize', function(fileSizeInBytes) {
  314. var i = -1;
  315. var byteUnits = [' kB', ' MB', ' GB', ' TB', 'PB', 'EB', 'ZB', 'YB'];
  316. do {
  317. fileSizeInBytes = fileSizeInBytes / 1024;
  318. i++;
  319. } while (fileSizeInBytes > 1024);
  320. return Math.max(fileSizeInBytes, 0.1).toFixed(1) + byteUnits[i];
  321. });