upload.js 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380
  1. var files = [];
  2. var sendingOffset = 0;
  3. var lastRequest = '';
  4. var dataView;
  5. var filesCount = 0;
  6. var currentUploadingFile = 0;
  7. var uploadOrder = [];
  8. var uploadingInProgress = 0;
  9. var fileUploadRequest;
  10. var chunkSize = 128;
  11. var totalUploaded = 0;
  12. var tpl = '<li class="working" id="file%filenum%"><div class="chart" id="graph%filenum%" data-percent="0"></div><p>%filename%<i>%filesize%</i></p><span class="delete" id="fileStatus%filenum%" onclick="DeleteFiles(%filenum%);"></span></li>';
  13. document.addEventListener("DOMContentLoaded", function() {
  14. var dropbox;
  15. dropbox = document.getElementById("dropbox");
  16. dropbox.addEventListener("dragenter", dragenter, false);
  17. dropbox.addEventListener("dragover", dragover, false);
  18. dropbox.addEventListener("drop", drop, false);
  19. UpdateFileList();
  20. UploadDir("http");
  21. });
  22. function dragenter(e) {
  23. e.stopPropagation();
  24. e.preventDefault();
  25. }
  26. function dragover(e) {
  27. e.stopPropagation();
  28. e.preventDefault();
  29. }
  30. function drop(e) {
  31. e.stopPropagation();
  32. e.preventDefault();
  33. var dt = e.dataTransfer;
  34. handleFiles(dt.files);
  35. }
  36. function handleFiles(tfiles) {
  37. var filesCount = tfiles.length;
  38. files = tfiles;
  39. currentUploadingFile = 0;
  40. uploadOrder = [];
  41. sendingOffset = 0;
  42. lastRequest = '';
  43. document.getElementById('fileList').innerHTML = '';
  44. var fileNames = {};
  45. for (var i = 0; i < filesCount; i++) {
  46. fileNames[uploadDir + tfiles[i].name] = i;
  47. }
  48. Keys(fileNames).sort(function(a,b){var c=a.toLowerCase(),d=b.toLowerCase();return c<d?-1:c>d?1:0}).forEach(function(item) {
  49. var i = fileNames[item];
  50. var append = tpl.replace(/%filename%/g, uploadDir + tfiles[i].name);
  51. append = append.replace(/%filesize%/g, formatFileSize(tfiles[i].size));
  52. append = append.replace(/%filenum%/g, i);
  53. document.getElementById('fileList').insertAdjacentHTML('beforeend', append);
  54. UpdateGraph(0, i);
  55. uploadOrder.push(i);
  56. });
  57. }
  58. function DeleteFiles(filenum) {
  59. var elem = document.getElementById('file' + filenum.toString());
  60. elem.parentNode.removeChild(elem);
  61. if (uploadingInProgress) {
  62. if (parseInt(filenum) != uploadOrder[currentUploadingFile]) {
  63. for (var i = 0; i < uploadOrder.length; i++) {
  64. if (uploadOrder[i] == filenum) {
  65. delete uploadOrder[i];
  66. }
  67. }
  68. }
  69. else {
  70. uploadingInProgress = 0;
  71. RemoveFile(files[uploadOrder[currentUploadingFile]].name + '.dnl');
  72. for (var i = 0; i < uploadOrder.length; i++) {
  73. if (uploadOrder[i] == filenum) {
  74. delete uploadOrder[i];
  75. }
  76. }
  77. currentUploadingFile++;
  78. totalUploaded = 0;
  79. sendingOffset = 0;
  80. lastRequest = '';
  81. fileUploadRequest.abort();
  82. fileUploadRequest = 0;
  83. UploadFiles();
  84. }
  85. }
  86. else {
  87. for (var i = 0; i < uploadOrder.length; i++) {
  88. if (uploadOrder[i] == filenum) {
  89. delete uploadOrder[i];
  90. }
  91. }
  92. }
  93. }
  94. function UploadFiles() {
  95. if (uploadOrder[currentUploadingFile] === undefined) {
  96. uploadingInProgress = 0;
  97. if (currentUploadingFile < files.length - 1) {
  98. currentUploadingFile++;
  99. UploadFiles();
  100. }
  101. return;
  102. }
  103. var fileNum = uploadOrder[currentUploadingFile];
  104. var file = files[fileNum];
  105. var chunkLen = 0;
  106. var filedata = '';
  107. uploadingInProgress = 1;
  108. var fr = new FileReader();
  109. fr.onload = function() {
  110. dataView = null;
  111. dataView = new Uint8Array(fr.result);
  112. if (file.size <= chunkSize) {
  113. sendingOffset = 0;
  114. chunkLen = file.size;
  115. for (var i = 0; i < dataView.length; i++) {
  116. if (dataView[i] < 16) {
  117. filedata += '0';
  118. }
  119. filedata += dataView[i].toString(16).toUpperCase();
  120. }
  121. }
  122. else {
  123. if (dataView.length - sendingOffset > chunkSize) {
  124. chunkLen = chunkSize;
  125. }
  126. else {
  127. chunkLen = dataView.length - sendingOffset;
  128. }
  129. for (var i = sendingOffset; i < sendingOffset + chunkLen; i++) {
  130. if (dataView[i] < 16) {
  131. filedata += '0';
  132. }
  133. filedata += dataView[i].toString(16).toUpperCase();
  134. }
  135. }
  136. fileUploadRequest = new XMLHttpRequest();
  137. fileUploadRequest.onreadystatechange = function() {
  138. if (fileUploadRequest.readyState != 4) return;
  139. if (fileUploadRequest.status == 200) {
  140. if (chunkLen + sendingOffset < dataView.length) {
  141. totalUploaded += chunkSize;
  142. UpdateGraph(Math.round((totalUploaded / file.size) * 100), uploadOrder[currentUploadingFile]);
  143. sendingOffset += chunkSize;
  144. UploadFiles();
  145. }
  146. else {
  147. var statusElement = document.getElementById('fileStatus' + uploadOrder[currentUploadingFile]);
  148. sendingOffset = 0;
  149. UpdateGraph(100, uploadOrder[currentUploadingFile]);
  150. uploadingInProgress = 0;
  151. UpdateFileList();
  152. totalUploaded = 0;
  153. if (statusElement) {
  154. statusElement.classList.add("uploaded");
  155. }
  156. if (currentUploadingFile < files.length) {
  157. currentUploadingFile++;
  158. UploadFiles();
  159. }
  160. }
  161. }
  162. else {
  163. UploadFiles();
  164. }
  165. fileUploadRequest = 0;
  166. }
  167. lastRequest = 'upload.lua?cmd=upload&filename=' + uploadDir + file.name + '&filesize=' + file.size + '&len=' + chunkLen + '&offset=' + sendingOffset + '&data=' + filedata;
  168. fileUploadRequest.timeout = 5000;
  169. fileUploadRequest.open('GET', lastRequest, true);
  170. fileUploadRequest.send();
  171. };
  172. fr.readAsArrayBuffer(file);
  173. }
  174. function UploadDir(dir) {
  175. if (uploadingInProgress == 0) {
  176. document.getElementById('dir').innerHTML = "/" + dir;
  177. uploadDir = dir;
  178. if (!(uploadDir == "")) {
  179. uploadDir += "/";
  180. }
  181. }
  182. }
  183. function formatFileSize(bytes) {
  184. if (typeof bytes !== 'number') {
  185. return '';
  186. }
  187. if (bytes >= 1073741824) {
  188. return (bytes / 1073741824).toFixed(2) + ' GB';
  189. }
  190. if (bytes >= 1048576) {
  191. return (bytes / 1048576).toFixed(2) + ' MB';
  192. }
  193. return (bytes / 1024).toFixed(2) + ' KB';
  194. }
  195. function UpdateGraph(percent, id) {
  196. var el = document.getElementById('graph' + id); // get canvas
  197. if (!el) {
  198. return;
  199. }
  200. var options = {
  201. percent: el.getAttribute('data-percent') || 0,
  202. size: el.getAttribute('data-size') || 48,
  203. lineWidth: el.getAttribute('data-line') || 8,
  204. rotate: el.getAttribute('data-rotate') || 0
  205. }
  206. var canvas = document.createElement('canvas');
  207. if (typeof(G_vmlCanvasManager) !== 'undefined') {
  208. G_vmlCanvasManager.initElement(canvas);
  209. }
  210. var ctx = canvas.getContext('2d');
  211. canvas.width = canvas.height = options.size;
  212. el.appendChild(canvas);
  213. ctx.translate(options.size / 2, options.size / 2); // change center
  214. ctx.rotate((-1 / 2 + options.rotate / 180) * Math.PI); // rotate -90 deg
  215. var radius = (options.size - options.lineWidth) / 2;
  216. function drawCircle(color, lineWidth, percent) {
  217. if (percent) {
  218. percent = Math.min(Math.max(0, percent), 1);
  219. ctx.beginPath();
  220. ctx.arc(0, 0, radius, 0, Math.PI * 2 * percent, false);
  221. ctx.strokeStyle = color;
  222. ctx.lineCap = 'round'; // butt, round or square
  223. ctx.lineWidth = lineWidth
  224. ctx.stroke();
  225. }
  226. };
  227. options.percent = percent;
  228. drawCircle('#2e3134', options.lineWidth + 1, 100 / 100);
  229. drawCircle('#007a96', options.lineWidth, options.percent / 100);
  230. }
  231. function Keys(obj) {
  232. var keys = [];
  233. for(var key in obj){
  234. if(obj.hasOwnProperty(key)){
  235. keys.push(key);
  236. }
  237. }
  238. return keys;
  239. }
  240. function UpdateFileList() {
  241. var fileListRequest = new XMLHttpRequest();
  242. fileListRequest.onreadystatechange = function() {
  243. if (fileListRequest.readyState != 4) return;
  244. if (fileListRequest.status == 200) {
  245. var fileInfo = JSON.parse(fileListRequest.responseText);
  246. var fileList = fileInfo['files'];
  247. document.getElementById('fileInfo').innerHTML = '';
  248. var tpl = '<li class="working"><p style="left: 30px;">%filenamelink%<i>%filesize%</i></p><span class="delete" id="fileStatus" onclick="RemoveFile(\'%filename%\');"></span></li>';
  249. var tplTotal = '<li class="working"><p style="left: 30px;">Used:<i>%used%</i></p></li><li class="working"><p style="left: 30px;">Free:<i>%free%</i></p></li><li class="working"><p style="left: 30px;">Total:<i>%total%</i></p></li>';
  250. var append, link;
  251. Keys(fileList).sort(function(a,b){var c=a.toLowerCase(),d=b.toLowerCase();return c<d?-1:c>d?1:0}).forEach(function(item) {
  252. if (!item.match(/\.lc$/ig) && item.match(/^http\//ig)) {
  253. link = item.replace(/\.gz$/g, '').replace(/^http\//g, '');
  254. append = tpl.replace(/%filenamelink%/g, '<a href="' + link + '" target="_blank">' + item + '</a>');
  255. }
  256. else {
  257. append = tpl.replace(/%filenamelink%/g, item);
  258. }
  259. append = append.replace(/%filename%/g, item);
  260. append = append.replace(/%filesize%/g, formatFileSize(parseInt(fileList[item])));
  261. document.getElementById('fileInfo').insertAdjacentHTML('beforeend', append);
  262. });
  263. append = tplTotal.replace(/%used%/g, formatFileSize(parseInt(fileInfo['used'])));
  264. append = append.replace(/%free%/g, formatFileSize(parseInt(fileInfo['free'])));
  265. append = append.replace(/%total%/g, formatFileSize(parseInt(fileInfo['total'])));
  266. document.getElementById('fileInfo').insertAdjacentHTML('beforeend', append);
  267. }
  268. else {
  269. }
  270. fileListRequest = null;
  271. }
  272. fileListRequest.open('GET', 'upload.lua?cmd=list', true);
  273. fileListRequest.send();
  274. }
  275. function RemoveFile(name) {
  276. var fileRemoveRequest = new XMLHttpRequest();
  277. fileRemoveRequest.onreadystatechange = function() {
  278. if (fileRemoveRequest.readyState != 4) return;
  279. if (fileRemoveRequest.status == 200) {
  280. UpdateFileList();
  281. }
  282. }
  283. fileRemoveRequest.open('GET', 'upload.lua?cmd=remove&filename=' + name, true);
  284. fileRemoveRequest.send();
  285. }