file_operation.html 34 KB

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