resumefilemanager.js 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190
  1. var uploadLog = function(message) {
  2. var uploadConsole = document.getElementById("upload-console");
  3. if(uploadConsole.childNodes.length > 15) {
  4. uploadConsole.removeChild(uploadConsole.childNodes[0]);
  5. }
  6. var textContainer = document.createElement("div");
  7. var textNode = document.createTextNode(message);
  8. textContainer.appendChild(textNode);
  9. uploadConsole.appendChild(textContainer);
  10. };
  11. var ResumeFileUpload = function(fileToUpload, retries) {
  12. this.finished = false;
  13. var self = this;
  14. this.start = function() {
  15. var file = fileManager.lookup(fileToUpload.filepath);
  16. if(file != null) {
  17. this.getAccessToken(file);
  18. } else {
  19. console.error("file not in expected upload list: " + fileToUpload.filepath);
  20. fileManager.batch.pool.fileFinished(fileToUpload.upload_id);
  21. }
  22. };
  23. this.getAccessToken = function(file) {
  24. var data = {};
  25. data.filePath = file.webkitRelativePath;
  26. data.fileType = file.type;
  27. data.project_id = fileManager.projectId;
  28. data.resume = true;
  29. var promise = ajaxPost("/api/putfileaccesstoken", data);
  30. promise.success = function(event) {
  31. self.readFileContents(file, event);
  32. };
  33. promise.failure = function(event) {
  34. console.error("failure getting the access token: " + fileToUpload.filepath);
  35. fileManager.batch.pool.fileFailed(fileToUpload, ++retries);
  36. };
  37. };
  38. this.readFileContents = function(file, auth) {
  39. fileReader = new FileReader();
  40. fileReader.onload = function(event) {
  41. self.putFile(auth.url, event.target.result, auth.headers);
  42. };
  43. fileReader.readAsArrayBuffer(file);
  44. };
  45. this.putFile = function(url, fileData, headers) {
  46. var promise = ajaxPut(url, fileData, headers);
  47. promise.success = function(event) {
  48. self.confirmUpload();
  49. };
  50. promise.failure = function(event) {
  51. console.error("failure uploading file: " + fileToUpload.filepath);
  52. fileManager.batch.pool.fileFailed(fileToUpload, ++retries);
  53. }
  54. };
  55. this.confirmUpload = function() {
  56. var data = {"project_id": fileManager.projectId, "upload_id": fileToUpload.upload_id};
  57. var promise = ajaxPost('/api/confirmupload2', data);
  58. promise.success = function(event) {
  59. self.finished = true;
  60. fileManager.batch.pool.fileFinished(fileToUpload.upload_id);
  61. uploadLog("Uploaded file "+ fileToUpload.filepath);
  62. };
  63. promise.failure = function(event) {
  64. console.error("unable to mark file as completed: "+ fileToUpload.filepath);
  65. fileManager.batch.pool.fileFailed(fileToUpload, ++retries);
  66. };
  67. };
  68. };
  69. var ResumePool = function() {
  70. this.slots = [];
  71. var maxSlots = 10;
  72. var maxRetries = 4;
  73. var self = this;
  74. this.start = function() {
  75. window.requestAnimationFrame(function() {
  76. for(var i = 0; i < maxSlots; i++) {
  77. self.processNextFile();
  78. }
  79. });
  80. };
  81. this.processNextFile = function() {
  82. var activeFile = fileManager.batch.resumeFiles.pop();
  83. if(activeFile != null) {
  84. self.slots.push(activeFile.upload_id);
  85. var uploader = new ResumeFileUpload(activeFile, 0);
  86. uploader.start();
  87. }
  88. if(self.slots.length <= 0) {
  89. fileManager.batch.poolFinished();
  90. }
  91. };
  92. this.fileFinished = function(uploadId) {
  93. var foundUpload = self.slots.indexOf(uploadId);
  94. if(foundUpload > -1) {
  95. self.slots.splice(foundUpload, 1);
  96. document.getElementById('progress-number').innerHTML = parseInt(document.getElementById('progress-number').innerHTML) - 1;
  97. }
  98. window.requestAnimationFrame(function() { self.processNextFile(); });
  99. };
  100. this.fileFailed = function(fileToUpload, retries) {
  101. if(retries >= maxRetries) {
  102. this.fileFinished(fileToUpload.upload_id);
  103. return;
  104. }
  105. console.warn("retrying file attempt "+ retries +": " + fileToUpload.filepath);
  106. var uploader = new ResumeFileUpload(fileToUpload, retries);
  107. uploader.start();
  108. };
  109. };
  110. var ResumeBatch = function() {
  111. this.resumeFiles = [];
  112. this.pool = new ResumePool();
  113. var offset = 0;
  114. var limit = 50;
  115. var remaining = 0;
  116. var self = this;
  117. this.start = function() {
  118. var fileRestoreData = {};
  119. fileRestoreData.project_id = fileManager.projectId;
  120. fileRestoreData.limit = limit;
  121. var fileRestorePromise = ajaxPost('/api/getfilestoresume', fileRestoreData);
  122. fileRestorePromise.success = function(event) {
  123. self.resumeFiles = event.files;
  124. console.log("Remaining: " + event.total);
  125. document.getElementById('progress-number').innerHTML = event.total;
  126. if(0 < self.resumeFiles.length) {
  127. self.pool.start();
  128. } else {
  129. fileManager.batchFinished();
  130. }
  131. };
  132. fileRestorePromise.failure = function(event) {
  133. console.error("unable to retrieve list of resume files");
  134. };
  135. };
  136. this.poolFinished = function() {
  137. offset += limit;
  138. uploadLog("--- Batch Finished ("+ offset +") ---");
  139. this.start();
  140. };
  141. };
  142. var ResumeFileManager = function() {
  143. this.fileDictionary = {};
  144. this.fileList = {};
  145. this.projectId = 0;
  146. this.batch = new ResumeBatch();
  147. this.process = function() {
  148. uploadLog("--- Processing Browser Files ---");
  149. this.fileList = document.getElementById('dir-input').files;
  150. for(var i = 0; i < this.fileList.length; i++){
  151. this.fileDictionary[this.fileList[i].webkitRelativePath] = i;
  152. }
  153. document.getElementById('progress-number').innerHTML = this.fileList.length;
  154. uploadLog("--- Ready to Begin ---");
  155. };
  156. this.resumeUpload = function(projectId) {
  157. this.projectId = projectId;
  158. this.batch.start();
  159. };
  160. this.lookup = function(filepath) {
  161. return this.fileList[this.fileDictionary[filepath]];
  162. }
  163. this.batchFinished = function() {
  164. uploadLog("--- Upload Complete! ---");
  165. console.log("Upload complete!");
  166. };
  167. };
  168. var fileManager = new ResumeFileManager();