file_operation.html 34 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733
  1. <html>
  2. <head>
  3. <title locale="title">File Operation</title>
  4. <meta charset="UTF-8">
  5. <meta name="viewport" content="width=device-width, initial-scale=1.0 user-scalable=no">
  6. <link rel="stylesheet" href="../../script/semantic/semantic.min.css">
  7. <script type="text/javascript" src="../../script/jquery.min.js"></script>
  8. <script type="text/javascript" src="../../script/semantic/semantic.min.js"></script>
  9. <script type="text/javascript" src="../../script/ao_module.js"></script>
  10. <script type="text/javascript" src="../../script/applocale.js"></script>
  11. <style>
  12. .banner{
  13. background-color:#4287f5;
  14. height:50px;
  15. padding:12px;
  16. padding-left:20px;
  17. padding-top:16px;
  18. }
  19. #opricon{
  20. position:absolute;
  21. top:0px;
  22. right:0px;
  23. width:80px;
  24. height:80px;
  25. }
  26. .title{
  27. color:white;
  28. font-size:130%;
  29. }
  30. .content{
  31. padding:12px;
  32. }
  33. .info{
  34. margin-top:3px;
  35. white-space: nowrap;
  36. overflow: hidden;
  37. text-overflow: ellipsis;
  38. }
  39. </style>
  40. </head>
  41. <body>
  42. <div class="banner">
  43. <div class="title" locale="banner/title">Calculating Operation</div>
  44. <img id="opricon" src="img/loading.png" class="ui image"></img>
  45. </div>
  46. <div class="content">
  47. <div class="info"><span locale="info/from">From:</span> <span id="src"></span></div>
  48. <div class="info"><span locale="info/to">To:</span> <span id="dest"></span></div>
  49. <div class="info"><span locale="info/progress">Progress:</span> <span id="progress"> <i class="loading spinner icon"></i> <span>Calculating</span></div>
  50. <div class="ui active small progress" style="margin-top:18px;">
  51. <div id="progressbar" class="bar" style="width:100%; background-color:#4287f5;"></div>
  52. </div>
  53. </div>
  54. <div class="ui modal" id="duplicateAction">
  55. <div class="content">
  56. <div class="description" style="padding: 0px !important;">
  57. <p><i class="big exclamation triangle icon"></i> <span>At least one file has the same filename with another existsing file. <b>Which action should be taken?</b></span></p><br>
  58. </div>
  59. </div>
  60. <div class="actions">
  61. <div class="ui labeled button" onclick="continueProcess('overwrite');">
  62. Overwrite
  63. </div>
  64. <div class="ui labeled button" onclick="continueProcess('skip');">
  65. Skip
  66. </div>
  67. <div class="ui labeled button" style="color: #2fb55c;" onclick="continueProcess('keep');">
  68. Rename & Keep
  69. </div>
  70. </div>
  71. </div>
  72. <script>
  73. /*
  74. ArOZ Online File Operation Listener
  75. Usage: Pass in the following JSON object as hash with encodeURIComponent after JSON stringify
  76. {
  77. opr: {move / copy / zip / unzip / download / zipAndDown / unzipAndOpen},
  78. src: {filelist, allow multiple files},
  79. dest: {filepath},
  80. //Optional paramters
  81. overwriteMode: {skip / overwrite / keep},
  82. callbackWindowID: {floatWindow ID},
  83. callbackFunction: {target Window Function Name as String}
  84. }
  85. **For download opr, it will first buffer into the browser memory.
  86. It is not recommended for files > 2GB (Firefox Limit)
  87. Example callbackFunction: "refreshList()" (string)
  88. */
  89. var operationConfig = null;
  90. var opr = "";
  91. var maxPathDisplayLength = 40;
  92. var legacyMode = !('WebSocket' in window || 'MozWebSocket' in window); //Use AJAX instead of WebSocket if legacy mode is activated
  93. var enterErrorMode = false;
  94. //Initalized floatWindow events
  95. ao_module_setFixedWindowSize();
  96. ao_module_setWindowSize(400,220);
  97. if (applocale){
  98. //Applocale found. Do localization
  99. applocale.init("../locale/file_operation.json", function(){
  100. applocale.translate();
  101. init();
  102. });
  103. }else{
  104. //Applocale not found. Is this a trim down version of ArozOS?
  105. applocale = {
  106. getString: function(key, original){
  107. return original;
  108. }
  109. }
  110. init();
  111. }
  112. function init(){
  113. console.log("Checking launch parameters...");
  114. if (window.location.hash.length > 0){
  115. //OK to proceed
  116. try{
  117. operationConfig = JSON.parse(decodeURIComponent(window.location.hash.substring(1)));
  118. //Check if there are any missing paratmers
  119. configValid = true;
  120. if (typeof operationConfig.opr == "undefined"){ configValid = false; }
  121. if (typeof operationConfig.src == "undefined"){ configValid = false; }
  122. if (typeof operationConfig.dest == "undefined"){ configValid = false; }
  123. if (!configValid){
  124. console.log("Invalid file operation config. Please see the file_operation.html source code for the correct config json object.")
  125. ao_module_close();
  126. return;
  127. }
  128. //Parse the missing argument if there are any
  129. if (typeof operationConfig.overwriteMode == "undefined"){
  130. operationConfig.overwriteMode = "skip";
  131. }
  132. //Update 17-12-2020, ask the user for overwrite mode if file duplicate exists
  133. if (operationConfig.overwriteMode == "ask"){
  134. //Check if any file duplication before proceeding
  135. console.log(operationConfig.src);
  136. $.ajax({
  137. url: "../../system/file_system/listDir",
  138. data: {dir: operationConfig.dest},
  139. success: function(filelist){
  140. //Check for duplication
  141. var duplicateFound = false;
  142. /*
  143. mainloop:
  144. for (var i = 0; i < filelist.length; i++){
  145. var desktopFile = filelist[i];
  146. for (var j = 0; j < operationConfig.src.length; j++){
  147. var srcfile = operationConfig.src[j];
  148. var srcFilename = srcfile.split("/").pop();
  149. if (srcFilename == desktopFile.Filename){
  150. duplicateFound = true
  151. break mainloop;
  152. }
  153. }
  154. };
  155. */
  156. duplicateFound = filelist.some(function(file){
  157. return operationConfig.src.includes(file);
  158. });
  159. if (duplicateFound){
  160. //Duplication found.
  161. $("#duplicateAction").modal({
  162. closable: false
  163. }).modal("show");
  164. }else{
  165. //Duplication not found. Start the operation with default mode
  166. operationConfig.overwriteMode = "skip";
  167. processOperations(operationConfig);
  168. }
  169. }
  170. })
  171. }else{
  172. //All information are defined. Process it now.
  173. processOperations(operationConfig)
  174. }
  175. }catch(ex){
  176. //Failed
  177. console.log("Argument parse error", ex);
  178. }
  179. }else{
  180. alert("Invalid use of File Operation Listener.")
  181. ao_module_close();
  182. }
  183. }
  184. function continueProcess(duplicateMode){
  185. operationConfig.overwriteMode = duplicateMode;
  186. $("#duplicateAction").modal("hide");
  187. processOperations(operationConfig)
  188. }
  189. function processOperations(operationConfig){
  190. //Update the display information
  191. $("#src").text(operationConfig.src);
  192. $("#dest").text(operationConfig.dest);
  193. opr = operationConfig.opr;
  194. updateTitle(operationConfig.src.length, operationConfig.opr);
  195. //Check which type of the oprs is about. And assign the related functions to start
  196. if (operationConfig.opr == "move"){
  197. $("#opricon").attr("src","img/move.gif");
  198. cut(operationConfig.src, operationConfig.dest, operationConfig.overwriteMode);
  199. }else if (operationConfig.opr == "copy"){
  200. $("#opricon").attr("src","img/copy.gif");
  201. copy(operationConfig.src, operationConfig.dest, operationConfig.overwriteMode);
  202. }else if (operationConfig.opr == "zip"){
  203. $("#opricon").attr("src","img/zip.gif");
  204. zip(operationConfig.src, operationConfig.dest, operationConfig.overwriteMode);
  205. }else if (operationConfig.opr == "unzip"){
  206. $("#opricon").attr("src","img/unzip.gif");
  207. unzip(operationConfig.src, operationConfig.dest, operationConfig.overwriteMode);
  208. }else if (operationConfig.opr == "unzipAndOpen"){
  209. $("#opricon").attr("src","img/unzip.gif");
  210. unzip(operationConfig.src, operationConfig.dest, operationConfig.overwriteMode, function(){
  211. //Open the target directory
  212. });
  213. }
  214. }
  215. //Unzip zip
  216. function unzip(srcList, dest, overwriteMode, callback=undefined){
  217. if (legacyMode){
  218. //Run in legacy mode
  219. requestCSRFToken(function(token){
  220. $.ajax({
  221. type: 'POST',
  222. url: `../../system/file_system/fileOpr`,
  223. data: {opr: "unzip" ,src: JSON.stringify(srcList), dest: dest, csrft: token},
  224. success: function(data){
  225. handleFinish(data);
  226. }
  227. });
  228. });
  229. }else{
  230. //Filter all + sign in the list
  231. var filteredSrcList = [];
  232. srcList.forEach(src => {
  233. filteredSrcList.push(src.split("+").join("{{plug_sign}}"));
  234. });
  235. //Open WebSocket
  236. var endpoint = getWSEndpoint() + `?opr=unzip&src=${encodeURIComponent(JSON.stringify(filteredSrcList))}&dest=${encodeURIComponent(dest)}&existsresp=${overwriteMode}`
  237. console.log(endpoint);
  238. var ws = new WebSocket(endpoint);
  239. ws.onopen = function(){
  240. //Do nothing. Just listen to the progress update
  241. };
  242. ws.onmessage = function (evt) {
  243. var data = evt.data;
  244. var progress = JSON.parse(data);
  245. console.log(progress);
  246. if (progress.Error != ""){
  247. //Something went wrong
  248. $("#progressbar").css("background-color", "#eb3f28");
  249. $("#opricon").attr("src", "img/error.png");
  250. enterErrorMode = true;
  251. alert(progress.Error);
  252. }else{
  253. //Update the progress display
  254. $("#progressbar").css("width", progress.Progress + "%");
  255. var currentSrc = truncate(progress.LatestFile, maxPathDisplayLength);
  256. var filteredDest = operationConfig.dest.trim();
  257. if (filteredDest.substr(filteredDest.length -1, 1) != "/"){
  258. filteredDest += "/"
  259. }
  260. var currentDest = truncate(filteredDest + progress.LatestFile, maxPathDisplayLength);
  261. $("#src").text(currentSrc);
  262. $("#dest").text(currentDest);
  263. $("#progress").text(progress.Progress + "%")
  264. if (progress.Progress == 100){
  265. //Set progress bar to green
  266. $("#progressbar").css("background-color", "#2bba35");
  267. }
  268. }
  269. };
  270. ws.onclose = function() {
  271. if (!enterErrorMode){
  272. $("#progressbar").css("background-color", "#2bba35");
  273. $("#progressbar").css("width", "100%");
  274. $("#progress").text("100%");
  275. $("#opricon").attr("src", "img/done.png")
  276. setTimeout(function(){
  277. if (operationConfig.opr == "unzipAndOpen"){
  278. //If open after unzip is required
  279. ao_module_openPath(operationConfig.dest);
  280. }
  281. ao_module_close();
  282. }, 1000);
  283. }
  284. };
  285. ws.onerror = function(event){
  286. console.error("WebSocket error observed:", event);
  287. legacyMode = true;
  288. console.log("Falling back to Legacy Mode");
  289. unzip(srcList, dest, overwriteMode, callback);
  290. }
  291. }
  292. }
  293. //Create zip
  294. function zip(srcList, dest, overwriteMode){
  295. if (legacyMode){
  296. //Run in legacy mode
  297. requestCSRFToken(function(token){
  298. $.ajax({
  299. type: 'POST',
  300. url: `../../system/file_system/fileOpr`,
  301. data: {opr: "zip" ,src: JSON.stringify(srcList), dest: dest, csrft: token},
  302. success: function(data){
  303. handleFinish(data);
  304. }
  305. });
  306. });
  307. }else{
  308. //Replace all + sign with tag
  309. var filteredSrcList = [];
  310. srcList.forEach(src => {
  311. filteredSrcList.push(src.split("+").join("{{plug_sign}}"));
  312. })
  313. //Start WebSocket connection
  314. var endpoint = getWSEndpoint() + `?opr=zip&src=${encodeURIComponent(JSON.stringify(filteredSrcList))}&dest=${encodeURIComponent(dest)}&existsresp=${overwriteMode}`
  315. console.log(endpoint);
  316. var ws = new WebSocket(endpoint);
  317. var srcZipRoot = "";
  318. ws.onopen = function() {
  319. console.log("File Operation WebSocket opened")
  320. //Emulate the src folder
  321. var srcDir = srcList[0].split("/");
  322. srcDir.pop();
  323. srcDir = srcDir.join("/");
  324. srcZipRoot = srcDir;
  325. var currentSrc = truncate(srcDir, maxPathDisplayLength);
  326. $("#src").text(currentSrc);
  327. //Emulate the dest folder
  328. var destFolderName = dest.substr(0, dest.length - 1).split('/').pop();
  329. destFolderName += ".zip";
  330. var currentDest = truncate(dest + destFolderName, maxPathDisplayLength);
  331. $("#dest").text(currentDest);
  332. };
  333. ws.onmessage = function (evt) {
  334. var data = evt.data;
  335. var progress = JSON.parse(data);
  336. if (progress.Error != ""){
  337. //Something went wrong
  338. $("#progressbar").css("background-color", "#eb3f28");
  339. enterErrorMode = true;
  340. alert(progress.Error);
  341. }else{
  342. //Update the progress display
  343. $("#progressbar").css("width", progress.Progress + "%");
  344. var currentSrc = truncate(srcZipRoot + "/" + progress.LatestFile, maxPathDisplayLength);
  345. var filteredDest = operationConfig.dest.trim();
  346. if (filteredDest.substr(filteredDest.length -1, 1) != "/"){
  347. filteredDest += "/"
  348. }
  349. var currentDest = truncate(filteredDest + progress.LatestFile, maxPathDisplayLength);
  350. $("#src").text(currentSrc);
  351. $("#dest").text(currentDest);
  352. $("#progress").text(progress.Progress + "%")
  353. if (progress.Progress == 100){
  354. //Set progress bar to green
  355. $("#progressbar").css("background-color", "#2bba35");
  356. }
  357. }
  358. };
  359. ws.onclose = function() {
  360. //Transfer finished! Set OK and close in 1 second
  361. if (!enterErrorMode){
  362. $("#progressbar").css("background-color", "#2bba35");
  363. $("#progressbar").css("width", "100%");
  364. $("#progress").text("100%")
  365. handleFinish({});
  366. }
  367. };
  368. ws.onerror = function(event){
  369. console.error("WebSocket error observed:", event);
  370. legacyMode = true;
  371. console.log("Falling back to Legacy Mode");
  372. zip(srcList, dest, overwriteMode);
  373. }
  374. }
  375. }
  376. function cut(srcList, dest, overwriteMode){
  377. if (legacyMode){
  378. console.log("WebSocket not found, Running in legacy mode");
  379. requestCSRFToken(function(token){
  380. $.ajax({
  381. type: 'POST',
  382. url: `../../system/file_system/fileOpr`,
  383. data: {opr: "move" ,src: JSON.stringify(srcList), dest: dest,existsresp: overwriteMode, csrft: token},
  384. success: function(data){
  385. handleFinish(data);
  386. }
  387. });
  388. });
  389. }else{
  390. //Replace all + sign in srclist with {{plus_sign}}
  391. var filteredSrcList = [];
  392. srcList.forEach(src => {
  393. filteredSrcList.push(src.split("+").join("{{plug_sign}}"));
  394. })
  395. //Use Websocket for operation updates
  396. var endpoint = getWSEndpoint() + `?opr=move&src=${encodeURIComponent(JSON.stringify(filteredSrcList))}&dest=${encodeURIComponent(dest)}&existsresp=${overwriteMode}`
  397. console.log(endpoint);
  398. var ws = new WebSocket(endpoint);
  399. ws.onopen = function() {
  400. console.log("File Operation WebSocket opened")
  401. };
  402. ws.onmessage = function (evt) {
  403. var data = evt.data;
  404. var progress = JSON.parse(data);
  405. if (progress.Error != ""){
  406. $("#progressbar").css("background-color", "#eb3f28");
  407. enterErrorMode = true;
  408. alert(progress.Error);
  409. }else{
  410. $("#progressbar").css("width", progress.Progress + "%");
  411. var currentSrc = truncate(operationConfig.src + "/" + progress.LatestFile, maxPathDisplayLength);
  412. var filteredDest = operationConfig.dest.trim();
  413. if (filteredDest.substr(filteredDest.length -1, 1) != "/"){
  414. filteredDest += "/"
  415. }
  416. var currentDest = truncate(filteredDest + progress.LatestFile, maxPathDisplayLength);
  417. $("#src").text(currentSrc);
  418. $("#dest").text(currentDest);
  419. $("#progress").text(progress.Progress + "%")
  420. if (progress.Progress == 100){
  421. //Set progress bar to green
  422. $("#progressbar").css("background-color", "#2bba35");
  423. }
  424. }
  425. };
  426. ws.onclose = function() {
  427. //Transfer finished! Set OK and close in 1 second
  428. if (!enterErrorMode){
  429. $("#progressbar").css("background-color", "#2bba35");
  430. $("#progressbar").css("width", "100%");
  431. $("#progress").text("100%")
  432. handleFinish({});
  433. }
  434. };
  435. ws.onerror = function(event){
  436. console.error("WebSocket error observed:", event);
  437. console.log("Falling back to Legacy Mode")
  438. legacyMode = true;
  439. cut(srcList, dest, overwriteMode)
  440. }
  441. }
  442. }
  443. function copy(srcList, dest, overwriteMode){
  444. if (legacyMode){
  445. //Open operation in legacy mode
  446. console.log("WebSocket not found, Running in legacy mode");
  447. requestCSRFToken(function(token){
  448. $.ajax({
  449. type: 'POST',
  450. url: `../../system/file_system/fileOpr`,
  451. data: {opr: "copy" ,src: JSON.stringify(srcList), dest: dest,existsresp: overwriteMode , csrft: token},
  452. success: function(data){
  453. handleFinish(data);
  454. }
  455. });
  456. });
  457. }else{
  458. var filteredSrcList = [];
  459. srcList.forEach(src => {
  460. filteredSrcList.push(src.split("+").join("{{plug_sign}}"));
  461. })
  462. //Use Websocket for operation updates
  463. var endpoint = getWSEndpoint() + `?opr=copy&src=${JSON.stringify(filteredSrcList)}&dest=${encodeURIComponent(dest)}&existsresp=${overwriteMode}`
  464. var ws = new WebSocket(endpoint);
  465. ws.onopen = function() {
  466. console.log("File Operation WebSocket opened")
  467. };
  468. ws.onmessage = function (evt) {
  469. var data = evt.data;
  470. var progress = JSON.parse(data);
  471. if (progress.Error != ""){
  472. $("#progressbar").css("background-color", "#eb3f28");
  473. enterErrorMode = true;
  474. alert(progress.Error);
  475. }else{
  476. $("#progressbar").css("width", progress.Progress + "%");
  477. var currentSrc = truncate(operationConfig.src + "/" + progress.LatestFile, maxPathDisplayLength);
  478. var filteredDest = operationConfig.dest.trim();
  479. if (filteredDest.substr(filteredDest.length -1, 1) != "/"){
  480. filteredDest += "/"
  481. }
  482. var currentDest = truncate(filteredDest + progress.LatestFile, maxPathDisplayLength);
  483. $("#src").text(currentSrc);
  484. $("#dest").text(currentDest);
  485. $("#progress").text(progress.Progress + "%")
  486. if (progress.Progress == 100){
  487. //Set progress bar to green
  488. $("#progressbar").css("background-color", "#2bba35");
  489. }
  490. }
  491. };
  492. ws.onclose = function() {
  493. //Transfer finished! Set OK and close in 1 second
  494. if (!enterErrorMode){
  495. $("#progressbar").css("background-color", "#2bba35");
  496. $("#progressbar").css("width", "100%");
  497. $("#progress").text("100%");
  498. handleFinish({});
  499. }
  500. };
  501. ws.onerror = function(event){
  502. console.error("WebSocket error observed:", event);
  503. console.log("Falling back to Legacy Mode")
  504. legacyMode = true;
  505. copy(srcList, dest, overwriteMode)
  506. }
  507. }
  508. }
  509. var truncate = function (fullStr, strLen, separator) {
  510. if (fullStr.length <= strLen) return fullStr;
  511. separator = separator || '...';
  512. var sepLen = separator.length,
  513. charsToShow = strLen - sepLen,
  514. frontChars = Math.ceil(charsToShow/2),
  515. backChars = Math.floor(charsToShow/2);
  516. return fullStr.substr(0, frontChars) +
  517. separator +
  518. fullStr.substr(fullStr.length - backChars);
  519. };
  520. function getWSEndpoint(){
  521. //Open opeartion in websocket
  522. let protocol = "wss://";
  523. if (location.protocol !== 'https:') {
  524. protocol = "ws://";
  525. }
  526. var port = window.location.port;
  527. if (window.location.port == ""){
  528. if (location.protocol !== 'https:') {
  529. port = "80";
  530. }else{
  531. port = "443";
  532. }
  533. }
  534. wsControlEndpoint = (protocol + window.location.hostname + ":" + port + "/system/file_system/ws/fileOpr");
  535. return wsControlEndpoint;
  536. }
  537. function updateTitle(fileNumber, opr){
  538. var title = "";
  539. if (opr == "move"){
  540. title = applocale.getString("title/moving","Moving ");
  541. }else if (opr == "copy"){
  542. title = applocale.getString("title/copying","Copying ");
  543. }else if (opr == "zip" || opr == "zipAndDownload"){
  544. title = applocale.getString("title/zipping","Zipping ");
  545. }else if (opr == "download"){
  546. title = applocale.getString("title/downloading","Downloading ");
  547. }else if (opr == "unzip" || opr == "unzipAndOpen"){
  548. title = applocale.getString("title/unzipping","Unzipping ");
  549. }
  550. title += fileNumber + " ";
  551. if (fileNumber == 1){
  552. title += applocale.getString("title/file"," File");
  553. }else{
  554. title += applocale.getString("title/files"," Files");
  555. }
  556. $(".title").text(title);
  557. }
  558. function handleFinish(data){
  559. if (data.error !== undefined){
  560. $("#progressbar").css("background-color","#db2828");
  561. $("#progressbar").parent().removeClass('active');
  562. $(".title").html(`<i class="remove icon"></i>` + applocale.getString("error/" + data.error,data.error));
  563. enterErrorMode = true;
  564. return
  565. }else{
  566. $("#progressbar").css("background-color","#21ba45");
  567. $("#progressbar").parent().removeClass('active');
  568. if (opr == "move" || opr == "copy" || opr == "zip" || opr == "unzip"){
  569. //Action completed. close window.
  570. setTimeout(function(){
  571. //Do callback if exists
  572. if (operationConfig.callbackWindowID == "desktop"){
  573. //Special call from desktop
  574. parent.eval(operationConfig.callbackFunction);
  575. }else if (operationConfig.callbackWindowID !== undefined && operationConfig.callbackFunction !== undefined){
  576. var callbackWindowObject = parent.getFloatWindowByID(operationConfig.callbackWindowID)
  577. var windowObject = $(callbackWindowObject).find("iframe")[0];
  578. if (windowObject == undefined || windowObject == null){
  579. //Caller no longer exists.
  580. }else{
  581. //Caller still exists. Do callback events
  582. //console.log(windowObject.contentWindow, operationConfig.callbackFunction);
  583. windowObject.contentWindow.eval(operationConfig.callbackFunction);
  584. }
  585. }
  586. //If the target or src is desktop, refresh desktop as well
  587. if(pathIsOnDesktop(operationConfig.dest) || pathIsOnDesktop(operationConfig.src[0])){
  588. parent.refresh(undefined, true);
  589. }
  590. if (!enterErrorMode){
  591. ao_module_close();
  592. }
  593. }, 1000);
  594. }else if (opr == "download"){
  595. //Create download from buffer
  596. }else if (opr == "zipAndDown"){
  597. //Download
  598. }else if (opr == "unzipAndOpen"){
  599. //Unzip and open the target directory
  600. setTimeout(function(){
  601. //Open the target directory
  602. ao_module_openPath(operationConfig.dest);
  603. //Close the window
  604. ao_module_close();
  605. }, 1000);
  606. }
  607. }
  608. console.log(data);
  609. }
  610. function pathIsOnDesktop(path){
  611. var filteredDest = path;
  612. if (filteredDest.substr(filteredDest.length - 1) == "/"){
  613. filteredDest = filteredDest.substr(0, filteredDest.length - 1);
  614. }
  615. var dirChunk = filteredDest.split("/");
  616. console.log(dirChunk);
  617. if (dirChunk.length == 2 || dirChunk.length == 3){
  618. if (dirChunk[0].toLowerCase() == "user:" && dirChunk[1].toLowerCase() == "desktop"){
  619. //This is a direct access desktop file
  620. return true;
  621. }
  622. }
  623. return false;
  624. }
  625. function requestCSRFToken(callback){
  626. $.ajax({
  627. url: "../../system/csrf/new",
  628. success: function(token){
  629. callback(token);
  630. }
  631. })
  632. }
  633. </script>
  634. </body>
  635. </html>