imapsync_form.js 27 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826
  1. // $Id: imapsync_form.js,v 1.28 2022/04/16 16:51:07 gilles Exp gilles $
  2. /*jslint browser: true*/ /*global $*/
  3. $(document).ready(
  4. function ()
  5. {
  6. "use strict";
  7. // Bootstrap popover and tooltip
  8. $("[data-toggle='tooltip']").tooltip();
  9. var readyStateStr = {
  10. "0": "Request not initialized",
  11. "1": "Server connection established",
  12. "2": "Response headers received",
  13. "3": "Processing request",
  14. "4": "Finished and response is ready"
  15. } ;
  16. var refresh_interval_ms = 6000 ;
  17. var refresh_interval_s = refresh_interval_ms / 1000 ;
  18. var test = {
  19. counter_all : 0 ,
  20. counter_ok : 0 ,
  21. counter_nok : 0 ,
  22. failed_tests : ""
  23. } ;
  24. var is = function is( expected, given, comment )
  25. {
  26. test.counter_all += 1 ;
  27. var message = test.counter_all + " - ["
  28. + expected
  29. + "] === ["
  30. + given
  31. + "] "
  32. + comment
  33. + "\n" ;
  34. if ( expected === given )
  35. {
  36. test.counter_ok += 1 ;
  37. message = "ok " + message ;
  38. }
  39. else
  40. {
  41. test.counter_nok += 1 ;
  42. test.failed_tests += "nb " + message + "\n" ;
  43. message = "not ok " + message ;
  44. }
  45. $("#tests").append( message ) ;
  46. } ;
  47. var note = function note( message )
  48. {
  49. $("#tests").append( message ) ;
  50. } ;
  51. var tests_last_x_lines = function tests_last_x_lines()
  52. {
  53. is( "", last_x_lines(), "last_x_lines: no args => empty string" ) ;
  54. is( "", last_x_lines(""), "last_x_lines: empty string => empty string" ) ;
  55. is( "abc", last_x_lines("abc"), "last_x_lines: abc => abc" ) ;
  56. is( "abc\ndef", last_x_lines("abc\ndef"), "last_x_lines: abc\ndef => abc\ndef" ) ;
  57. is( "def", last_x_lines("abc\ndef", -1), "last_x_lines: abc\ndef -1 => def\n" ) ;
  58. is( "", last_x_lines("abc\ndef", 0), "last_x_lines: abc\ndef 0 => empty string" ) ;
  59. is( "abc\ndef", last_x_lines("abc\ndef", -10), "last_x_lines: last 10 of 2 lines => 2 lines" ) ;
  60. is( "4\n5\n", last_x_lines("1\n2\n3\n4\n5\n", -3), "last_x_lines: last 3 lines of 5 lines" ) ;
  61. is( "3\n4\n5", last_x_lines("1\n2\n3\n4\n5", -3), "last_x_lines: last 3 lines of 5 lines" ) ;
  62. } ;
  63. var last_x_lines = function last_x_lines( string, num )
  64. {
  65. if ( undefined === string || 0 === num )
  66. {
  67. return "" ;
  68. }
  69. return string.split(/\r?\n/).slice(num).join("\n") ;
  70. } ;
  71. var last_eta = function last_eta( string )
  72. {
  73. // return the last occurrence of the substring "ETA: ...\n"
  74. // or "ETA: unknown" or ""
  75. var eta ;
  76. var last_found ;
  77. if ( undefined === string )
  78. {
  79. return "" ;
  80. }
  81. var eta_re = /ETA:.*\n/g ;
  82. eta = string.match( eta_re ) ;
  83. if ( eta )
  84. {
  85. last_found = eta[eta.length -1 ] ;
  86. return last_found ;
  87. }
  88. else
  89. {
  90. return "ETA: unknown" ;
  91. }
  92. }
  93. var tests_last_eta = function tests_last_eta()
  94. {
  95. is( "", last_eta( ), "last_eta: no args => empty string" ) ;
  96. is(
  97. "ETA: unknown",
  98. last_eta( "" ),
  99. "last_eta: empty => empty string" ) ;
  100. is( "ETA: unknown",
  101. last_eta( "ETA" ),
  102. "last_eta: ETA => empty string" ) ;
  103. is( "ETA: unknown", last_eta( "ETA: but no CR" ),
  104. "last_eta: ETA: but no CR => empty string" ) ;
  105. is(
  106. "ETA: with CR\n",
  107. last_eta( "Blabla ETA: with CR\n" ),
  108. "last_eta: ETA: with CR => ETA: with CR"
  109. ) ;
  110. is(
  111. "ETA: 2 with CR\n",
  112. last_eta( "Blabla ETA: 1 with CR\nBlabla ETA: 2 with CR\n" ),
  113. "last_eta: several ETA: with CR => ETA: 2 with CR"
  114. ) ;
  115. }
  116. var tests_decompose_eta_line = function tests_decompose_eta_line()
  117. {
  118. var eta_obj ;
  119. var eta_str = "ETA: Wed Jul 3 14:55:27 2019 1234 s 123/4567 msgs left\n" ;
  120. eta_obj = decompose_eta_line( "" ) ;
  121. is(
  122. "",
  123. eta_obj.str,
  124. "decompose_eta_line: no match => undefined"
  125. ) ;
  126. eta_obj = decompose_eta_line( eta_str ) ;
  127. is(
  128. eta_str,
  129. eta_str,
  130. "decompose_eta_line: str is str"
  131. ) ;
  132. is(
  133. eta_str,
  134. eta_obj.str,
  135. "decompose_eta_line: str back"
  136. ) ;
  137. is(
  138. "Wed Jul 3 14:55:27 2019",
  139. eta_obj.date,
  140. "decompose_eta_line: date"
  141. ) ;
  142. is(
  143. "1234",
  144. eta_obj.seconds_left,
  145. "decompose_eta_line: seconds_left"
  146. ) ;
  147. is(
  148. "123",
  149. eta_obj.msgs_left,
  150. "decompose_eta_line: msgs_left"
  151. ) ;
  152. is(
  153. "4567",
  154. eta_obj.msgs_total,
  155. "decompose_eta_line: msgs_total"
  156. ) ;
  157. is(
  158. "4444",
  159. eta_obj.msgs_done(),
  160. "decompose_eta_line: msgs_done"
  161. ) ;
  162. is(
  163. "97.31",
  164. eta_obj.percent_done(),
  165. "decompose_eta_line: percent_done"
  166. ) ;
  167. is(
  168. "2.69",
  169. eta_obj.percent_left(),
  170. "decompose_eta_line: percent_left"
  171. ) ;
  172. } ;
  173. var decompose_eta_line = function decompose_eta_line( eta_str )
  174. {
  175. var eta_obj ;
  176. var eta_array ;
  177. var regex_eta = /^ETA:\s+(.*?)\s+([0-9]+)\s+s\s+([0-9]+)\/([0-9]+)\s+msgs\s+left\n?$/ ;
  178. eta_array = regex_eta.exec( eta_str ) ;
  179. if ( null !== eta_array )
  180. {
  181. eta_obj = {
  182. str : eta_str,
  183. date : eta_array[1],
  184. seconds_left : eta_array[2],
  185. msgs_left : eta_array[3],
  186. msgs_total : eta_array[4],
  187. msgs_done : function() {
  188. var diff = eta_obj.msgs_total - eta_obj.msgs_left ;
  189. return( diff.toString() ) ;
  190. },
  191. percent_done : function() {
  192. var percent ;
  193. if ( 0 === eta_obj.msgs_total )
  194. {
  195. return "0" ;
  196. }
  197. else
  198. {
  199. percent = ( eta_obj.msgs_total - eta_obj.msgs_left ) / eta_obj.msgs_total * 100 ;
  200. return( percent.toFixed(2) ) ;
  201. }
  202. },
  203. percent_left : function() {
  204. var percent ;
  205. if ( 0 === eta_obj.msgs_total )
  206. {
  207. return "0" ;
  208. }
  209. else
  210. {
  211. percent = ( eta_obj.msgs_left / eta_obj.msgs_total * 100 ) ;
  212. return( percent.toFixed(2) ) ;
  213. }
  214. }
  215. } ;
  216. }
  217. else
  218. {
  219. eta_obj = {
  220. str : "",
  221. date : "?",
  222. seconds_left : "?",
  223. msgs_left : "?",
  224. msgs_total : "?",
  225. msgs_done : "?",
  226. percent_done : function() { return "" ; },
  227. percent_left : function() { return "" ; }
  228. } ;
  229. }
  230. return eta_obj ;
  231. } ;
  232. var extract_eta = function extract_eta( xhr )
  233. {
  234. var eta_obj ;
  235. var slice_length ;
  236. var slice_log ;
  237. var eta_str ;
  238. if ( xhr.readyState === 4 )
  239. {
  240. slice_length = -24000 ;
  241. }
  242. else
  243. {
  244. slice_length = -2400 ;
  245. }
  246. slice_log = xhr.responseText.slice( slice_length ) ;
  247. eta_str = last_eta( slice_log ) ;
  248. // $("#tests").append( "extract_eta eta_str: " + eta_str + "\n" ) ;
  249. eta_obj = decompose_eta_line( eta_str ) ;
  250. return eta_obj ;
  251. } ;
  252. var progress_bar_update = function progress_bar_update( eta_obj )
  253. {
  254. if ( eta_obj.str.length )
  255. {
  256. $("#progress-bar-done").css( "width", eta_obj.percent_done() + "%" ).attr( "aria-valuenow", eta_obj.percent_done() ) ;
  257. $("#progress-bar-left").css( "width", eta_obj.percent_left() + "%" ).attr( "aria-valuenow", eta_obj.percent_left() ) ;
  258. $("#progress-bar-done").text( eta_obj.percent_done() + "% " + "done" ) ;
  259. $("#progress-bar-left").text( eta_obj.percent_left() + "% " + "left" ) ;
  260. }
  261. else
  262. {
  263. $("#progress-bar-done").text( "unknown % " + "done" ) ;
  264. $("#progress-bar-left").text( "unknown % " + "left" ) ;
  265. }
  266. return ;
  267. } ;
  268. var refreshLog = function refreshLog( xhr )
  269. {
  270. var eta_obj ;
  271. var eta_str ;
  272. $( "#imapsync_current" ).load( "imapsync_current.txt" ) ;
  273. eta_obj = extract_eta( xhr ) ;
  274. progress_bar_update( eta_obj ) ;
  275. if ( xhr.readyState === 4 )
  276. {
  277. // end of sync
  278. $("#progress-txt").text(
  279. "Ended. It remains "
  280. + eta_obj.msgs_left + " messages to be synced" ) ;
  281. $( "#output" ).text( xhr.responseText ) ;
  282. }
  283. else
  284. {
  285. eta_str = eta_obj.str + " (refresh every " + refresh_interval_s + " s)" ;
  286. eta_str = eta_str.replace(/(\r\n|\n|\r)/gm, "") ; // trim newlines
  287. //$("#tests").append( "refreshLog eta_str: " + eta_str + "\n" ) ;
  288. $( "#progress-txt" ).text( eta_str ) ;
  289. var last_lines = last_x_lines( xhr.responseText.slice(-2000), -10)
  290. $( "#output" ).text( last_lines ) ;
  291. }
  292. }
  293. var handleRun = function handleRun(xhr, timerRefreshLog)
  294. {
  295. $("#console").text(
  296. "Status: " + xhr.status + " " + xhr.statusText + "\n"
  297. + "State: " + readyStateStr[xhr.readyState] + "\n" ) ;
  298. if ( xhr.readyState === 4 ) {
  299. // var headers = xhr.getAllResponseHeaders();
  300. // $("#console").append(headers);
  301. // $("#console").append("See the completed log\n");
  302. clearInterval( timerRefreshLog ) ;
  303. refreshLog( xhr ) ; // a last time
  304. // back to enable state for next run
  305. $("#bt-sync").prop("disabled", false) ;
  306. $( "#imapsync_current" ).load( "imapsync_current.txt" ) ;
  307. }
  308. }
  309. var imapsync = function imapsync()
  310. {
  311. var querystring = $("#form").serialize() ;
  312. $("#abort").text("\n\n") ; // clean abort console
  313. $("#output").text("Here comes the log!\n\n") ;
  314. if ( "imap.gmail.com" === $("#host1").val() )
  315. {
  316. querystring = querystring + "&gmail1=on" ;
  317. }
  318. if ( "imap.gmail.com" === $("#host2").val() )
  319. {
  320. querystring = querystring + "&gmail2=on" ;
  321. }
  322. // Same for "outlook.office365.com"
  323. if ( "outlook.office365.com" === $("#host1").val() )
  324. {
  325. querystring = querystring + "&office1=on" ;
  326. }
  327. if ( "outlook.office365.com" === $("#host2").val() )
  328. {
  329. querystring = querystring + "&office2=on" ;
  330. }
  331. // querystring = querystring + "&tmphash=" + tmphash( ) ;
  332. var xhr ;
  333. xhr = new XMLHttpRequest() ;
  334. var timerRefreshLog = setInterval(
  335. function ()
  336. {
  337. refreshLog( xhr ) ;
  338. }, refresh_interval_ms ) ;
  339. xhr.onreadystatechange = function ()
  340. {
  341. handleRun( xhr, timerRefreshLog ) ;
  342. } ;
  343. xhr.open( "POST", "/cgi-bin/imapsync", true ) ;
  344. xhr.setRequestHeader( "Content-type",
  345. "application/x-www-form-urlencoded" ) ;
  346. xhr.send( querystring ) ;
  347. }
  348. var handleAbort = function handleAbort( xhr )
  349. {
  350. $( "#abort" ).text(
  351. "Status: " + xhr.status + " " + xhr.statusText + "\n"
  352. + "State: " + readyStateStr[xhr.readyState] + "\n\n" ) ;
  353. if ( xhr.readyState === 4 )
  354. {
  355. $("#abort").append(xhr.responseText);
  356. $("#bt-sync").prop("disabled", false);
  357. $("#bt-abort").prop("disabled", false); // back for next abort
  358. }
  359. }
  360. var abort = function abort()
  361. {
  362. var querystring = $("#form").serialize() + "&abort=on";
  363. var xhr;
  364. xhr = new XMLHttpRequest();
  365. xhr.onreadystatechange = function ()
  366. {
  367. handleAbort(xhr);
  368. };
  369. xhr.open("POST", "/cgi-bin/imapsync", true);
  370. xhr.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
  371. xhr.send(querystring);
  372. }
  373. var store = function store( id )
  374. {
  375. var stored ;
  376. //$( "#tests" ).append( "Eco: " + id + " type is " + $( id ).attr( "type" ) + "\n" ) ;
  377. if ( "text" === $( id ).attr( "type" ) || "password" === $( id ).attr( "type" ) )
  378. {
  379. localStorage.setItem( id, $(id).val() ) ;
  380. stored = $( id ).val() ;
  381. }
  382. else if ( "checkbox" === $( id ).attr( "type" ) )
  383. {
  384. //$( "#tests" ).append( "Eco: " + id + " checked is " + $( id )[0].checked + "\n" ) ;
  385. localStorage.setItem( id, $( id )[0].checked ) ;
  386. stored = $( id )[0].checked ;
  387. }
  388. return stored ;
  389. }
  390. var retrieve = function retrieve( id )
  391. {
  392. var retrieved ;
  393. //$( "#tests" ).append( "Eco: " + id + " type is " + $( id ).attr( "type" ) + " length is " + $( id ).length + "\n" ) ;
  394. if ( "text" === $( id ).attr( "type" ) || "password" === $( id ).attr( "type" ) )
  395. {
  396. $( id ).val( localStorage.getItem( id ) ) ;
  397. retrieved = $( id ).val() ;
  398. }
  399. else if ( "checkbox" === $( id ).attr( "type" ) )
  400. {
  401. //$( "#tests" ).append( "Eco: " + id + " getItem is " + localStorage.getItem( id ) + "\n" ) ;
  402. $( id )[0].checked = JSON.parse( localStorage.getItem( id ) ) ;
  403. retrieved = $( id )[0].checked ;
  404. }
  405. return retrieved ;
  406. }
  407. var tests_store_retrieve = function tests_store_retrieve()
  408. {
  409. if ( $("#tests").length !== 0 )
  410. {
  411. is( 1, 1, "one equals one" ) ;
  412. // isnot( 0, 1, "zero differs one" ) ;
  413. // no exist
  414. is( undefined, store( "#test_noexists" ),
  415. "store: #test_noexists" ) ;
  416. is( undefined, retrieve( "#test_noexists" ),
  417. "retrieve: #test_noexists" ) ;
  418. is( undefined, retrieve( "#test_noexists2" ),
  419. "retrieve: #test_noexists2" ) ;
  420. // input text
  421. $("#test_text" ).val( "foo" ) ;
  422. is( "foo", $("#test_text" ).val( ), "#test_text val = foo" ) ;
  423. is( "foo", store( "#test_text" ), "store: #test_text" ) ;
  424. $("#test_text" ).val( "bar" ) ;
  425. is( "bar", $("#test_text" ).val( ), "#test_text val = bar" ) ;
  426. is( "foo", retrieve( "#test_text" ), "retrieve: #test_text = foo" ) ;
  427. is( "foo", $("#test_text" ).val( ), "#test_text val = foo" ) ;
  428. // input check button
  429. $( "#test_checkbox" ).prop( "checked", true );
  430. is( true, store( "#test_checkbox" ), "store: #test_checkbox checked" ) ;
  431. $( "#test_checkbox" ).prop( "checked", false );
  432. is( true, retrieve( "#test_checkbox" ), "retrieve: #test_checkbox = true" ) ;
  433. $( "#test_checkbox" ).prop( "checked", false );
  434. is( false, store( "#test_checkbox" ), "store: #test_checkbox not checked" ) ;
  435. $( "#test_checkbox" ).prop( "checked", true );
  436. is( false, retrieve( "#test_checkbox" ), "retrieve: #test_checkbox = false" ) ;
  437. }
  438. }
  439. var store_form = function store_form()
  440. {
  441. if ( Storage !== "undefined")
  442. {
  443. // Code for localStorage.
  444. store("#user1") ;
  445. store("#password1") ;
  446. store("#host1") ;
  447. store("#subfolder1") ;
  448. store("#showpassword1") ;
  449. store("#user2") ;
  450. store("#password2") ;
  451. store("#host2") ;
  452. store("#subfolder2") ;
  453. store("#showpassword2") ;
  454. store("#dry") ;
  455. store("#justlogin") ;
  456. store("#justfolders") ;
  457. store("#justfoldersizes") ;
  458. localStorage.account1_background_color = $("#account1").css("background-color") ;
  459. localStorage.account2_background_color = $("#account2").css("background-color") ;
  460. }
  461. }
  462. var show_extra_if_needed = function show_extra_if_needed()
  463. {
  464. if ( $("#subfolder1").length && $("#subfolder1").val().length > 0 )
  465. {
  466. $(".extra_param").show() ;
  467. }
  468. if ( $("#subfolder2").length && $("#subfolder2").val().length > 0 )
  469. {
  470. $(".extra_param").show() ;
  471. }
  472. }
  473. var retrieve_form = function retrieve_form()
  474. {
  475. if ( Storage !== "undefined" )
  476. {
  477. // Code for localStorage.
  478. retrieve( "#user1" ) ;
  479. retrieve( "#password1" ) ;
  480. // retrieve("#showpassword1") ;
  481. retrieve( "#host1" ) ;
  482. retrieve( "#subfolder1" ) ;
  483. retrieve( "#user2" ) ;
  484. retrieve( "#password2" ) ;
  485. // retrieve("#showpassword2") ;
  486. retrieve( "#host2" ) ;
  487. retrieve( "#subfolder2" ) ;
  488. retrieve( "#dry" ) ;
  489. retrieve( "#justlogin" ) ;
  490. retrieve( "#justfolders" ) ;
  491. retrieve( "#justfoldersizes" ) ;
  492. // In case, how to restore the original color from css file.
  493. // localStorage.removeItem( "account1_background_color" ) ;
  494. // localStorage.removeItem( "account2_background_color" ) ;
  495. if ( localStorage.account1_background_color )
  496. {
  497. $("#account1").css("background-color",
  498. localStorage.account1_background_color ) ;
  499. }
  500. if ( localStorage.account2_background_color )
  501. {
  502. $("#account2").css("background-color",
  503. localStorage.account2_background_color ) ;
  504. }
  505. // Show the extra parameters if they are not empty because it would
  506. // be dangerous to retrieve them without showing them
  507. show_extra_if_needed() ;
  508. }
  509. }
  510. var showpassword = function showpassword( id, button )
  511. {
  512. var x = document.getElementById( id );
  513. if ( button.checked )
  514. {
  515. x.type = "text";
  516. } else {
  517. x.type = "password";
  518. }
  519. }
  520. var tests_cryptojs = function tests_cryptojs()
  521. {
  522. if ( $("#tests").length !== 0 )
  523. {
  524. if (typeof CryptoJS === 'undefined')
  525. {
  526. is( true, typeof CryptoJS !== 'undefined', "CryptoJS is available" ) ;
  527. note( "CryptoJS is not available on this site. Ask the admin to fix this.\n" ) ;
  528. }
  529. else if (typeof CryptoJS.SHA256 !== "function")
  530. {
  531. is( "function", typeof CryptoJS.SHA256, "CryptoJS.SHA256 is a function" ) ;
  532. note( "CryptoJS.SHA256 function is not available on this site. Ask the admin to fix this.\n" ) ;
  533. }
  534. else
  535. {
  536. // safe to use the function
  537. is( "function", typeof CryptoJS.SHA256, "CryptoJS.SHA256 is a function" ) ;
  538. is( "2f77668a9dfbf8d5848b9eeb4a7145ca94c6ed9236e4a773f6dcafa5132b2f91", sha256("Message"), "sha256 Message" ) ;
  539. is( "26429a356b1d25b7d57c0f9a6d5fed8a290cb42374185887dcd2874548df0779", sha256("caca"), "sha256 caca" ) ;
  540. is( "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", sha256(""), "sha256 ''" ) ;
  541. is( tmphash(), tmphash(), "tmphash" ) ;
  542. $("#user1").val("test1") ;
  543. $("#password1").val("secret1") ;
  544. $("#host1").val("test1.lamiral.info") ;
  545. $("#user2").val("test2") ;
  546. $("#password2").val("secret2") ;
  547. $("#host2").val("test2.lamiral.info") ;
  548. is( "20d2b4917cf69114876b4c8779af543e89c5871c6ada68107619722e55af1101", tmphash(), "tmphash like testslive" ) ;
  549. $("#user1").val("") ;
  550. $("#password1").val("") ;
  551. $("#host1").val("") ;
  552. $("#user2").val("") ;
  553. $("#password2").val("") ;
  554. $("#host2").val("") ;
  555. }
  556. }
  557. }
  558. var sha256 = function sha256( string )
  559. {
  560. var hash = CryptoJS.SHA256( string ) ;
  561. var hash_hex = hash.toString( CryptoJS.enc.Hex ) ;
  562. return( hash_hex ) ;
  563. }
  564. var tmphash = function tmphash()
  565. {
  566. var string = "" ;
  567. string = string.concat(
  568. $("#user1").val(), $("#password1").val(), $("#host1").val(),
  569. $("#user2").val(), $("#password2").val(), $("#host2").val(),
  570. )
  571. return( sha256( string ) ) ;
  572. }
  573. var init = function init()
  574. {
  575. // in case of a manual refresh, start with
  576. $("#bt-sync").prop("disabled", false);
  577. $("#bt-abort").prop("disabled", false);
  578. $("#progress-bar-left").css( "width", 100 + "%" ).attr( "aria-valuenow", 100 ) ;
  579. $("#showpassword1").click(
  580. function ( event )
  581. {
  582. var button = event.target ;
  583. showpassword( "password1", button ) ;
  584. }
  585. );
  586. $("#showpassword2").click(
  587. function ( event )
  588. {
  589. //$("#tests").append( "\nthat1=" + JSON.stringify( event.target, undefined, 4 ) ) ;
  590. var button = event.target ;
  591. showpassword( "password2", button ) ;
  592. }
  593. );
  594. $("#bt-sync").click(
  595. function ()
  596. {
  597. $( "#imapsync_current" ).load( "imapsync_current.txt" ) ;
  598. $("#bt-sync").prop("disabled", true) ;
  599. $("#bt-abort").prop("disabled", false) ;
  600. $("#progress-txt").text( "ETA: coming soon" ) ;
  601. store_form() ;
  602. imapsync() ;
  603. }
  604. );
  605. $("#bt-abort").click(
  606. function ()
  607. {
  608. $( "#imapsync_current" ).load( "imapsync_current.txt" ) ;
  609. $("#bt-sync").prop("disabled", true);
  610. $("#bt-abort").prop("disabled", true);
  611. abort();
  612. $( "#imapsync_current" ).load( "imapsync_current.txt" ) ;
  613. }
  614. );
  615. var swap = function swap( p1, p2 )
  616. {
  617. var temp = $( p2 ).val( ) ;
  618. $( p2 ).val( $( p1 ).val( ) ) ;
  619. $( p1 ).val( temp ) ;
  620. } ;
  621. $("#swap").click(
  622. function()
  623. {
  624. // swaping colors can't use swap()
  625. var temp1 = $("#account1").css("background-color") ;
  626. var temp2 = $("#account2").css("background-color") ;
  627. $("#account1").css("background-color", temp2 );
  628. $("#account2").css("background-color", temp1 );
  629. swap( $("#user1"), $("#user2") ) ;
  630. swap( $("#password1"), $("#password2") ) ;
  631. swap( $("#host1"), $("#host2") ) ;
  632. swap( $("#subfolder1"), $("#subfolder2") ) ;
  633. var temp = $("#showpassword1")[0].checked ;
  634. $("#showpassword1")[0].checked = $("#showpassword2")[0].checked ;
  635. $("#showpassword2")[0].checked = temp ;
  636. showpassword( "password1", $("#showpassword1")[0] ) ;
  637. showpassword( "password2", $("#showpassword2")[0] ) ;
  638. }
  639. ) ;
  640. if ( "imapsync.lamiral.info" === location.hostname )
  641. {
  642. $( "#local_bandwidth" ).collapse( "show" ) ;
  643. $( "#local_status_dbmon" ).collapse( "show" ) ;
  644. $( "#local_status_hetrix" ).collapse( "show" ) ;
  645. $( "#imapsync_advice_hours" ).collapse( "show" ) ;
  646. $( "#imapsync_current" ).load( "imapsync_current.txt" ) ;
  647. }
  648. else if ( "lamiral.info" === location.hostname )
  649. {
  650. $( "#local_bandwidth" ).collapse( "show" ) ;
  651. $( "#local_status_dbmon" ).collapse( "show" ) ;
  652. $( "#local_status_hetrix" ).collapse( "show" ) ;
  653. $( "#imapsync_advice_hours" ).collapse( "show" ) ;
  654. $( "#imapsync_current" ).load( "imapsync_current.txt" ) ;
  655. }
  656. }
  657. var tests_bilan = function tests_bilan( nb_attended_test )
  658. {
  659. // attended number of tests: nb_attended_test
  660. $("#tests").append( "1.." + test.counter_all + "\n" ) ;
  661. if ( test.counter_nok > 0 )
  662. {
  663. $("#tests").append(
  664. "\nFAILED tests \n"
  665. + test.failed_tests
  666. ) ;
  667. $("#tests").collapse("show") ;
  668. }
  669. // Summary of tests: failed 0 tests, run xx tests,
  670. // expected to run yy tests.
  671. if ( test.counter_all !== nb_attended_test )
  672. {
  673. $("#tests").append( "# Looks like you planned "
  674. + nb_attended_test
  675. + " tests but ran "
  676. + test.counter_all + ".\n"
  677. ) ;
  678. $("#tests").collapse("show") ;
  679. }
  680. } ;
  681. var tests = function tests( nb_attended_test )
  682. {
  683. if ( $("#tests").length !== 0 )
  684. {
  685. tests_store_retrieve( ) ;
  686. tests_last_eta( ) ;
  687. tests_decompose_eta_line( ) ;
  688. tests_last_x_lines( ) ;
  689. // tests_cryptojs( ) ;
  690. // The following test can be used to check that if a test fails
  691. // then all the tests are shown to the user.
  692. //is( 0, 1, "this test always fails" ) ;
  693. tests_bilan( nb_attended_test ) ;
  694. // If you want to always see the tests, uncomment the following
  695. // line
  696. //$("#tests").collapse("show") ;
  697. }
  698. }
  699. init( ) ;
  700. tests( 38 ) ;
  701. retrieve_form( ) ;
  702. }
  703. );