mirror of
https://github.com/imapsync/imapsync.git
synced 2025-08-01 14:54:26 +02:00
1.945
This commit is contained in:
parent
0797e48248
commit
275436c5a0
126 changed files with 25270 additions and 4380 deletions
94
X/cgi_memo
94
X/cgi_memo
|
@ -1,6 +1,6 @@
|
|||
#!/bin/sh
|
||||
|
||||
# $Id: cgi_memo,v 1.45 2019/02/10 14:28:53 gilles Exp gilles $
|
||||
# $Id: cgi_memo,v 1.48 2019/06/25 16:49:11 gilles Exp gilles $
|
||||
|
||||
if test -n "$1"; then
|
||||
echoq() { echo "$@" ; } # not quiet mode
|
||||
|
@ -149,7 +149,7 @@ grep_any() {
|
|||
|
||||
grep_load() {
|
||||
echo G_Load.txt
|
||||
egrep -o 'Load is ..?\... ..?\... ..?\...' grep_stats.txt > G_Load.txt
|
||||
egrep -o 'Load is ..?\... ..?\... ..?\... .*' grep_stats.txt > G_Load.txt
|
||||
}
|
||||
|
||||
grep_all2() {
|
||||
|
@ -169,16 +169,21 @@ stat_patterns_list() {
|
|||
}
|
||||
|
||||
|
||||
echoq stat_load
|
||||
stat_load() {
|
||||
echo -n 'Load min: ' ; datamash --format=%6.1f -W min 3 min 4 min 5 < G_Load.txt
|
||||
echo -n 'Load q1: ' ; datamash --format=%6.1f -W q1 3 q1 4 q1 5 < G_Load.txt
|
||||
echo -n 'Load median: ' ; datamash --format=%6.1f -W median 3 median 4 median 5 < G_Load.txt
|
||||
echo -n 'Load mean: ' ; datamash --format=%6.1f -W mean 3 mean 4 mean 5 < G_Load.txt
|
||||
echo -n 'Load q3: ' ; datamash --format=%6.1f -W q3 3 q3 4 q3 5 < G_Load.txt
|
||||
echo -n 'Load max: ' ; datamash --format=%6.1f -W max 3 max 4 max 5 < G_Load.txt
|
||||
|
||||
|
||||
stat_load()
|
||||
{
|
||||
echo -n 'Load 1 min 5 min 15 min ' ; grep -o 'on.*cores' G_Load.txt|uniq
|
||||
echo -n 'Load min: ' ; datamash --format=%3.1f -W min 3 min 4 min 5 < G_Load.txt
|
||||
echo -n 'Load q1: ' ; datamash --format=%3.1f -W q1 3 q1 4 q1 5 < G_Load.txt
|
||||
echo -n 'Load median: ' ; datamash --format=%3.1f -W median 3 median 4 median 5 < G_Load.txt
|
||||
echo -n 'Load mean: ' ; datamash --format=%3.1f -W mean 3 mean 4 mean 5 < G_Load.txt
|
||||
echo -n 'Load q3: ' ; datamash --format=%3.1f -W q3 3 q3 4 q3 5 < G_Load.txt
|
||||
echo -n 'Load max: ' ; datamash --format=%3.1f -W max 3 max 4 max 5 < G_Load.txt
|
||||
}
|
||||
|
||||
|
||||
|
||||
datamash_file_op_index() {
|
||||
file="$1"
|
||||
op="${2:-mean}"
|
||||
|
@ -205,7 +210,8 @@ stat_any() {
|
|||
}
|
||||
|
||||
echoq stat_all
|
||||
stat_all() {
|
||||
stat_all()
|
||||
{
|
||||
stat_load ; echo
|
||||
# stat_any G_REMOTE_ADDR.txt
|
||||
# stat_any G_REMOTE_HOST.txt
|
||||
|
@ -225,7 +231,30 @@ stat_all() {
|
|||
stat_any G_Detected_errors.txt 2
|
||||
stat_any G_Exiting_with_return_value.txt 5 # GROUP
|
||||
stat_any G_Memory_consumption_at_the_end.txt 7
|
||||
stat_any G_Messages_found_in_host1_not_in_host2.txt 9
|
||||
stat_any G_Messages_found_in_host2_not_in_host1.txt 9
|
||||
#stat_any G_failure_Error_login.txt
|
||||
echo "Data made at" `date -r grep_stats.txt`
|
||||
}
|
||||
|
||||
stat_transfer_time_mean()
|
||||
{
|
||||
datamash_file_op_index G_Transfer_time.txt mean
|
||||
}
|
||||
|
||||
stat_throuput_since_day_one_in_days()
|
||||
{
|
||||
number_of_syncs=`number_of_syncs`
|
||||
days_since_first_use=`days_since_first_use`
|
||||
c "$number_of_syncs / $days_since_first_use"
|
||||
}
|
||||
|
||||
stat_queue_mean()
|
||||
{
|
||||
stat_throuput_since_day_one_in_days=`stat_throuput_since_day_one_in_days`
|
||||
stat_transfer_time_mean=`stat_transfer_time_mean`
|
||||
stat_queue_mean_raw=`c "$stat_throuput_since_day_one_in_days * $stat_transfer_time_mean / 3600 / 24"`
|
||||
printf "%2.2f\n" $stat_queue_mean_raw
|
||||
}
|
||||
|
||||
echoq dirs_of_syncs_finished_recently
|
||||
|
@ -257,7 +286,7 @@ logfiles_finished_recently()
|
|||
|
||||
last_dirs_written()
|
||||
{
|
||||
ls -tr | tail -800
|
||||
ls -tr | tail -1800
|
||||
}
|
||||
|
||||
last_file_written_in_dir()
|
||||
|
@ -268,7 +297,7 @@ last_file_written_in_dir()
|
|||
is_dir_running_imapsync()
|
||||
{
|
||||
test -d "$1" || return 1
|
||||
test -f "$1/imapsync.pid" && PID=`cat "$1/imapsync.pid"` &&
|
||||
test -f "$1/imapsync.pid" && PID=`head -1 "$1/imapsync.pid"` &&
|
||||
ps -p $PID -o comm= > /dev/null
|
||||
}
|
||||
|
||||
|
@ -318,7 +347,7 @@ pids_of_imapsync_not_writing_since_x_secondes()
|
|||
do
|
||||
is_dir_running_imapsync "$d" &&
|
||||
is_file_older_than `last_file_written_in_dir "$d"` "$x_secondes" &&
|
||||
cat "$d/imapsync.pid" && echo -n " "
|
||||
head -1 "$d/imapsync.pid" | tr '\n' ' '
|
||||
|
||||
done
|
||||
|
||||
|
@ -327,7 +356,7 @@ pids_of_imapsync_not_writing_since_x_secondes()
|
|||
kill_HUP_pids_of_imapsync_not_writing_since_x_secondes()
|
||||
{
|
||||
pids_not_writing=`pids_of_imapsync_not_writing_since_x_secondes ${1:-900}`
|
||||
test -n "$pids_not_writing" && echo kill -HUP "$pids_not_writing" && kill -HUP "$pids_not_writing"
|
||||
test -n "$pids_not_writing" && echo kill -HUP "$pids_not_writing" # && kill -HUP "$pids_not_writing"
|
||||
}
|
||||
|
||||
|
||||
|
@ -385,7 +414,7 @@ watch_new_runs() {
|
|||
inotifywait . -e create 2>/dev/null | { read path action f
|
||||
echo $f
|
||||
sleep 2
|
||||
test -f $f/imapsync.pid && PID=`cat $f/imapsync.pid` && echo PID $PID
|
||||
test -f $f/imapsync.pid && PID=`head -1 $f/imapsync.pid` && echo PID $PID
|
||||
echo -e '\a'
|
||||
}
|
||||
done
|
||||
|
@ -394,7 +423,7 @@ watch_new_runs() {
|
|||
echoq pidfiles_running_and_not_running
|
||||
pidfiles_running_and_not_running() {
|
||||
ls -tr | while read f; do
|
||||
test -f $f/imapsync.pid && PID=`cat $f/imapsync.pid` && echo -n "$PID " &&
|
||||
test -f $f/imapsync.pid && PID=`head -1 $f/imapsync.pid` && echo -n "$PID " &&
|
||||
{ ps -p $PID -o comm= | tr '\n' ' ' && { test -f /proc/$PID/oom_score &&
|
||||
{ echo -12 > /proc/$PID/oom_adj ; } && echo -n "oom_score " && cat /proc/$PID/oom_score | tr '\n' ' ' ; : ; }
|
||||
} &&
|
||||
|
@ -406,7 +435,7 @@ pidfile_dandling() {
|
|||
pidfile_dandling_DIR=$1
|
||||
test -d $pidfile_dandling_DIR || return 2
|
||||
test -f $pidfile_dandling_DIR/imapsync.pid || return 3
|
||||
pidfile_dandling_PID=`cat $pidfile_dandling_DIR/imapsync.pid`
|
||||
pidfile_dandling_PID=`head -1 $pidfile_dandling_DIR/imapsync.pid`
|
||||
#echo "$pidfile_dandling_PID"
|
||||
test -n "$pidfile_dandling_PID" || return 4
|
||||
test "$pidfile_dandling_PID" -ge 1 || return 5
|
||||
|
@ -423,10 +452,11 @@ echoq pidfiles_not_running
|
|||
pidfiles_not_running() {
|
||||
ls -tr | while read f; do
|
||||
if pidfile_dandling "$f" ; then
|
||||
pidfiles_not_running_PID=`cat $f/imapsync.pid`
|
||||
pidfiles_not_running_PID=`head -1 $f/imapsync.pid`
|
||||
echo -n "rm $f/imapsync.pid # "
|
||||
{ ls -tr $f/LOG_imapsync/* 2>/dev/null |tail -1 ; } | tr '\n' ' '
|
||||
echo "# PID $pidfiles_not_running_PID"
|
||||
#head -2 $f/imapsync.pid
|
||||
fi
|
||||
done
|
||||
}
|
||||
|
@ -464,7 +494,11 @@ seconds_to_days_hours_echo() {
|
|||
date --date="1 day ago" > /dev/null && echo "echo $(date -ud "@${1:-0}" +'$((%s/3600/24)) days %_H hours %_M min %_S sec')" && return
|
||||
}
|
||||
|
||||
|
||||
printf_this_one_div10()
|
||||
{
|
||||
num=$1
|
||||
printf "% $((num/10))s\n" $1
|
||||
}
|
||||
|
||||
echoq 'runs_per_day 7 # last 7 days'
|
||||
runs_per_day() {
|
||||
|
@ -472,7 +506,10 @@ runs_per_day() {
|
|||
start=${1:-$historic_start}
|
||||
for cc in `count 0 $start`; do
|
||||
DATE=`date_x_days_ago $cc`
|
||||
echo -n "$DATE $cc days ago: "; find . -maxdepth 1 -mtime $cc -ls |wc -l
|
||||
# find on FreeBSD finds nothing with -mtime 0
|
||||
test FreeBSD = `uname -s` && cc=`expr 1 + $cc`
|
||||
runs_this_day=`find . -maxdepth 1 -mtime $cc -ls |wc -l`
|
||||
echo -n "$DATE $cc days ago: " ; printf_this_one_div10 $runs_this_day
|
||||
done
|
||||
}
|
||||
|
||||
|
@ -556,7 +593,8 @@ nb_syncs_badly_finished() {
|
|||
nb_syncs_badly_finished=`echo $logfiles_finished_recently | xargs grep -i 'Exiting with return value' | grep -v 'return value 0' | wc -l `
|
||||
echo $nb_syncs_badly_finished / $nb_logfiles_finished_recently
|
||||
cat <<EOF
|
||||
logfiles_finished_recently $1 | xargs grep -i 'Exiting with return value' | grep -v 'return value 0'
|
||||
logfiles_finished_recently $1 | xargs grep -i 'Exiting with return value' | grep -v 'return value 0'
|
||||
logfiles_finished_recently $1 | xargs grep -i 'Exiting with return value' | grep -v 'return value 0' | grep -o 'Exiting with return value.*' | sort | uniq -c | sort -n
|
||||
EOF
|
||||
}
|
||||
|
||||
|
@ -593,13 +631,18 @@ summary_compute2() {
|
|||
&& summary_display
|
||||
}
|
||||
|
||||
number_of_syncs()
|
||||
{
|
||||
list_all_logs | wc -l
|
||||
}
|
||||
|
||||
echoq summary_display
|
||||
summary_display() {
|
||||
vnstat_gen > /dev/null
|
||||
echo "Start date of /X (aaaa mm dd): `first_use` (`days_since_first_use` days of service)"
|
||||
echo -n "Number of /X users: " ; number_of_X_users
|
||||
echo -n "Number of /X accounts synced: " ; nb_migrations_launched
|
||||
echo -n "Number of /X syncs: " ; list_all_logs| grep -v abort.txt | wc -l
|
||||
echo -n "Number of /X syncs: " ; number_of_syncs
|
||||
echo -n "Total volume /X transferred: " ; total_volume_transferred
|
||||
echo -n "Total messages /X transferred: " ; total_messages_transferred
|
||||
echo -n "Biggest transfer: " ; biggest_transfer
|
||||
|
@ -607,6 +650,8 @@ summary_display() {
|
|||
echo -n "Biggest message transferred: " ; biggest_message_transferred
|
||||
echo -n "Biggest bandwidth rate: " ; biggest_bandwidth_rate
|
||||
echo -n "Longest transfer: " ; seconds_to_days_hours `longest_transfer`
|
||||
echo -n "Queue length mean is: " ; stat_queue_mean
|
||||
echo "Data made at" `date -r grep_stats.txt`
|
||||
}
|
||||
|
||||
echoq sync_ks2_i005
|
||||
|
@ -623,8 +668,9 @@ sync_ks2_i005()
|
|||
&& summary_compute2 \
|
||||
&& echo sending txt back to ks2 \
|
||||
&& rsync -av /home/imapsync_cgi_ks2/*txt root@ks2:/var/tmp/imapsync_cgi/ \
|
||||
&& summary_display \
|
||||
&& date \
|
||||
&& pwd
|
||||
&& pwd
|
||||
}
|
||||
|
||||
echoq watch_number_of_imapsync_running
|
||||
|
|
|
@ -1,16 +1,29 @@
|
|||
|
||||
|
||||
/* $Id: imapsync_form.css,v 1.1 2018/01/27 21:58:41 gilles Exp gilles $ */
|
||||
/* $Id: imapsync_form.css,v 1.5 2019/06/25 21:31:44 gilles Exp gilles $ */
|
||||
|
||||
#account1 {
|
||||
background-color: DodgerBlue ;
|
||||
// background-color: DodgerBlue ;
|
||||
background-color: Fuchsia ;
|
||||
}
|
||||
|
||||
#account2 {
|
||||
background-color: DarkTurquoise ;
|
||||
}
|
||||
|
||||
#parameters {
|
||||
// background-color: GreenYellow ;
|
||||
// background-color: White ;
|
||||
}
|
||||
|
||||
#progress {
|
||||
text-align: center ;
|
||||
font-size: 1.6em ;
|
||||
margin: 0 0 0px;
|
||||
}
|
||||
|
||||
.padd0 {
|
||||
padding-left: 0px ;
|
||||
padding-right: 0px ;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
112
X/imapsync_form.html
Normal file → Executable file
112
X/imapsync_form.html
Normal file → Executable file
|
@ -1,5 +1,5 @@
|
|||
<!DOCTYPE html>
|
||||
<!-- $Id: imapsync_form.html,v 1.62 2019/02/01 21:34:28 gilles Exp gilles $ -->
|
||||
<!-- $Id: imapsync_form.html,v 1.75 2019/06/27 05:27:13 gilles Exp gilles $ -->
|
||||
|
||||
<html lang="en" id="top">
|
||||
|
||||
|
@ -20,9 +20,7 @@
|
|||
|
||||
|
||||
<noscript>
|
||||
<style>
|
||||
.scripton {display:none;}
|
||||
</style>
|
||||
<link rel="stylesheet" href="noscript.css">
|
||||
</noscript>
|
||||
|
||||
</head>
|
||||
|
@ -30,22 +28,33 @@
|
|||
<body>
|
||||
|
||||
|
||||
<div class="hidden scripton">
|
||||
<pre id="tests">
|
||||
</pre>
|
||||
<input type="checkbox" id="test_checkbox">
|
||||
<input type="text" id="test_text">
|
||||
<input type="radio" id="test_radio" name="test_radio" value="first" >
|
||||
<input type="radio" id="test_radio" name="test_radio" value="second" >
|
||||
</div>
|
||||
|
||||
<div class="container-fluid" >
|
||||
|
||||
<div class="row">
|
||||
<div class="text-center">
|
||||
<a href="https://imapsync.lamiral.info/">
|
||||
<img alt="Imapsync home" src="https://imapsync.lamiral.info/X/logo_imapsync_Xn.png" height="38" width="60">
|
||||
<img alt="Imapsync home" title="Imapsync home page" src="https://imapsync.lamiral.info/X/logo_imapsync_Xn.png" height="38" width="60">
|
||||
</a>
|
||||
<a href="#top" class="btn btn-info active" role="button">Top</a>
|
||||
<a href="#top" title="Top of the page" class="btn btn-info " role="button">Top</a>
|
||||
<!-- <a href="#payment" class="btn btn-success" data-toggle="collapse">Pricing</a> -->
|
||||
<a href="#buttons" class="btn btn-info scripton" role="button">Consoles</a>
|
||||
<a href="#bottom" class="btn btn-info" role="button">Bottom</a>
|
||||
<!-- <a href="#buttons" class="btn btn-info scripton" role="button">Consoles</a> -->
|
||||
<a href="#bottom" title="Bottom of the page" class="btn btn-info active" role="button">Bottom</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<h1 class="text-center">Imapsync online</h1>
|
||||
|
||||
<p class="text-center"> <strong>Copy</strong>/synchronize a <strong>complete</strong> mailbox to another, without <strong>duplicates!</strong></p>
|
||||
|
||||
<!-- Paypal part start
|
||||
new: NDGMR6TLFZ926
|
||||
old: H2YTURNFT4XT4
|
||||
|
@ -57,11 +66,11 @@ old: H2YTURNFT4XT4
|
|||
<a href="#payment" class="btn btn-warning btn-lg" data-toggle="collapse">Pricing</a>
|
||||
</div>
|
||||
-->
|
||||
|
||||
|
||||
<!-- the "in" makes the form not collapsed by default
|
||||
Remove the in in order to mask the pricing section
|
||||
<div id="payment" class="well text-center collapse in" > -->
|
||||
<div id="payment" class="well text-center collapse in" >
|
||||
<div id="payment" class="well text-center collapse out" >
|
||||
<p class="lead">Pay by usage type</p>
|
||||
<form action="https://www.paypal.com/cgi-bin/webscr" method="post" target="_blank">
|
||||
<input type="hidden" name="cmd" value="_s-xclick" />
|
||||
|
@ -91,37 +100,40 @@ old: H2YTURNFT4XT4
|
|||
</form>
|
||||
</div>
|
||||
<!-- Paypal part end -->
|
||||
|
||||
|
||||
|
||||
|
||||
<form id="form" action="/cgi-bin/imapsync" method="post" autocomplete="on">
|
||||
<div class="row">
|
||||
<div id="account1" class="col-md-6" >
|
||||
<fieldset>
|
||||
<legend class="text-center h2">Source account</legend>
|
||||
<fieldset>
|
||||
<legend class="text-center h2">IMAP source mailbox</legend>
|
||||
|
||||
<label for="user1">--user1</label>
|
||||
<label for="user1">Login</label>
|
||||
<div class="input-group form-group">
|
||||
<span class="input-group-addon"><i class="glyphicon glyphicon-user"> </i></span>
|
||||
<input
|
||||
data-toggle="tooltip" data-placement="top" title="It is usually an email address or its left part before @"
|
||||
data-toggle="tooltip" data-placement="bottom" title="It is usually an email address or its left part before @"
|
||||
type="text" class="form-control input-lg" id="user1" name="user1" tabindex="1"
|
||||
placeholder="Enter source login name">
|
||||
placeholder="Enter login name">
|
||||
</div>
|
||||
|
||||
<label for="password1">--password1</label>
|
||||
<label for="password1">Password</label>
|
||||
<label class="checkbox-inline out">
|
||||
<input type="checkbox" id="showpassword1"> show password
|
||||
</label>
|
||||
<div class="input-group form-group">
|
||||
<span class="input-group-addon"><i class="glyphicon glyphicon-lock"></i></span>
|
||||
<input
|
||||
data-toggle="tooltip" data-placement="top" title="Passwords are not stored on the server"
|
||||
data-toggle="tooltip" data-placement="bottom" title="Passwords are not stored on the server"
|
||||
type="password" class="form-control input-lg" id="password1" name="password1" tabindex="2"
|
||||
placeholder="Enter password">
|
||||
</div>
|
||||
|
||||
<label for="host1">--host1</label>
|
||||
<label for="host1">Server</label>
|
||||
<div class="input-group form-group">
|
||||
<span class="input-group-addon"><i class="glyphicon glyphicon-cloud"></i></span>
|
||||
<input
|
||||
data-toggle="tooltip" data-placement="top" title="IMAP transfers are done with encryption if the servers support it."
|
||||
data-toggle="tooltip" data-placement="bottom" title="IMAP transfers are done with encryption if the servers support it."
|
||||
list="servers1" type="text" class="form-control input-lg" id="host1" name="host1" tabindex="3"
|
||||
placeholder="Enter imap source server name or IP address">
|
||||
<datalist id="servers1">
|
||||
|
@ -141,36 +153,39 @@ old: H2YTURNFT4XT4
|
|||
<div>
|
||||
<br>
|
||||
</div>
|
||||
</fieldset>
|
||||
</fieldset>
|
||||
</div>
|
||||
|
||||
|
||||
<div id="account2" class="col-md-6" >
|
||||
<fieldset>
|
||||
<legend class="text-center h2">Destination account</legend>
|
||||
<fieldset>
|
||||
<legend class="text-center h2">IMAP destination mailbox</legend>
|
||||
|
||||
<label for="user2">--user2</label>
|
||||
<label for="user2">Login</label>
|
||||
<div class="input-group form-group">
|
||||
<span class="input-group-addon"><i class="glyphicon glyphicon-user"></i></span>
|
||||
<input
|
||||
data-toggle="tooltip" data-placement="top" title="It is usually an email address or its left part before @"
|
||||
data-toggle="tooltip" data-placement="bottom" title="It is usually an email address or its left part before @"
|
||||
type="text" class="form-control input-lg" id="user2" name="user2" tabindex="6"
|
||||
placeholder="Enter destination login name">
|
||||
placeholder="Enter login name">
|
||||
</div>
|
||||
<label for="password2">--password2</label>
|
||||
<label for="password2">Password</label>
|
||||
<label class="checkbox-inline out">
|
||||
<input type="checkbox" id="showpassword2"> show password
|
||||
</label>
|
||||
<div class="input-group form-group">
|
||||
<span class="input-group-addon"><i class="glyphicon glyphicon-lock"></i></span>
|
||||
<input
|
||||
data-toggle="tooltip" data-placement="top" title="Passwords are not stored on the server"
|
||||
data-toggle="tooltip" data-placement="bottom" title="Passwords are not stored on the server"
|
||||
type="password" class="form-control input-lg" id="password2" name="password2" tabindex="7"
|
||||
placeholder="Enter password">
|
||||
</div>
|
||||
|
||||
<label for="host2">--host2</label>
|
||||
<label for="host2">Server</label>
|
||||
<div class="input-group form-group">
|
||||
<span class="input-group-addon"><i class="glyphicon glyphicon-cloud"></i></span>
|
||||
<input
|
||||
data-toggle="tooltip" data-placement="top" title="IMAP transfers are done with encryption if the servers support it."
|
||||
data-toggle="tooltip" data-placement="bottom" title="IMAP transfers are done with encryption if the servers support it."
|
||||
list="servers2" type="text" class="form-control input-lg" id="host2" name="host2" tabindex="8"
|
||||
placeholder="Enter imap destination server name or IP address">
|
||||
<datalist id="servers2">
|
||||
|
@ -189,30 +204,31 @@ old: H2YTURNFT4XT4
|
|||
<div>
|
||||
<br>
|
||||
</div>
|
||||
</fieldset>
|
||||
</fieldset>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<input type="hidden" name="automap" value="on">
|
||||
<input type="hidden" name="addheader" value="on">
|
||||
<!--
|
||||
<input type="hidden" name="simulong" value="3600">
|
||||
-->
|
||||
<!-- --#>
|
||||
<input type="hidden" name="simulong" value="360">
|
||||
<#!-- -->
|
||||
<a name="buttons"></a>
|
||||
<hr>
|
||||
|
||||
<!-- Classical button to go to the log only -->
|
||||
<noscript>
|
||||
<button type="submit" class="btn btn-success btn-lg center-block btn-block">Go sync!</button>
|
||||
<button type="submit" class="btn btn-success btn-lg center-block btn-block">Go sync!</button>
|
||||
</noscript>
|
||||
|
||||
<!-- Javascript buttons using xhr -->
|
||||
<!-- Javascript buttons using xhr -->
|
||||
<div class="row scripton">
|
||||
<div class="col-sm-6 padd0" >
|
||||
<button id="bt-sync" type="button"
|
||||
class="btn btn-success btn-lg center-block btn-block"
|
||||
tabindex="11"
|
||||
data-toggle="tooltip" data-placement="top" title="Launch the sync! You can abort the sync with the red Abort button nearby or by closing the tab/window."
|
||||
data-toggle="tooltip" data-placement="top"
|
||||
title="Launch the sync! You can abort the sync with the red Abort button nearby or by closing the tab/window."
|
||||
>
|
||||
Sync or resync!<br>
|
||||
<span class="glyphicon glyphicon-envelope"></span>
|
||||
|
@ -223,7 +239,8 @@ old: H2YTURNFT4XT4
|
|||
<div class="col-sm-6 padd0" >
|
||||
<button id="bt-abort" type="button"
|
||||
class="btn btn-danger btn-lg center-block btn-block" tabindex="12"
|
||||
data-toggle="tooltip" data-placement="top" title="You can abort and restart the sync later, no duplicates should happen"
|
||||
data-toggle="tooltip" data-placement="top"
|
||||
title="Abort the sync! You can restart the sync later, no duplicates should happen."
|
||||
>
|
||||
Abort!<br>
|
||||
<span class="glyphicon glyphicon-scissors"></span>
|
||||
|
@ -232,8 +249,11 @@ old: H2YTURNFT4XT4
|
|||
</div>
|
||||
</form>
|
||||
|
||||
|
||||
|
||||
<div class="row scripton" id="consoles">
|
||||
|
||||
<pre id="progress" ></pre>
|
||||
|
||||
<div class="col-sm-6 well">
|
||||
<h2 class="text-center">Console of imapsync run</h2>
|
||||
<pre id="console">
|
||||
|
@ -297,13 +317,13 @@ old: H2YTURNFT4XT4
|
|||
<div class="row">
|
||||
<div class="text-center">
|
||||
<a href="https://imapsync.lamiral.info/">
|
||||
<img alt="Imapsync home" src="https://imapsync.lamiral.info/X/logo_imapsync_Xn.png" height="38" width="60">
|
||||
<img alt="Imapsync home page" src="https://imapsync.lamiral.info/X/logo_imapsync_Xn.png" height="38" width="60">
|
||||
</a>
|
||||
<a href="#top" class="btn btn-info " role="button">Top</a>
|
||||
<a href="#buttons" class="btn btn-info scripton" role="button">Consoles</a>
|
||||
<a href="#bottom" class="btn btn-info active" role="button">Bottom</a>
|
||||
<a href="#top" title="Top of the page" class="btn btn-info " role="button">Top</a>
|
||||
<!-- <a href="#buttons" class="btn btn-info scripton" role="button">Consoles</a> -->
|
||||
<a href="#bottom" title="Bottom of the page" class="btn btn-info active" role="button">Bottom</a>
|
||||
<br>
|
||||
<small> ($Id: imapsync_form.html,v 1.62 2019/02/01 21:34:28 gilles Exp gilles $) </small><br>
|
||||
<small> ($Id: imapsync_form.html,v 1.75 2019/06/27 05:27:13 gilles Exp gilles $) </small><br>
|
||||
Terms and conditions for anything: <a href="https://imapsync.lamiral.info/LICENSE">No limits to do anything with this work and this license!</a><br>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -326,7 +346,7 @@ crossorigin="anonymous"
|
|||
|
||||
|
||||
<script
|
||||
src="imapsync_form.js"
|
||||
src="imapsync_form.js"
|
||||
>
|
||||
</script>
|
||||
|
||||
|
|
|
@ -1,104 +1,453 @@
|
|||
|
||||
// $Id: imapsync_form.js,v 1.2 2018/01/27 21:58:52 gilles Exp gilles $
|
||||
// $Id: imapsync_form.js,v 1.8 2019/06/25 16:41:43 gilles Exp gilles $
|
||||
|
||||
/*jslint browser: true*/ /*global $*/
|
||||
$(document).ready(function () {
|
||||
"use strict";
|
||||
// Bootstrap popover and tooltip
|
||||
$("[data-toggle='tooltip']").tooltip();
|
||||
|
||||
var readyStateStr = {
|
||||
"0": "Request not initialized",
|
||||
"1": "Server connection established",
|
||||
"2": "Response headers received",
|
||||
"3": "Processing request",
|
||||
"4": "Finished and response is ready"
|
||||
};
|
||||
|
||||
function refreshLog(xhr) {
|
||||
$("#output").html(xhr.responseText);
|
||||
}
|
||||
$(document).ready(
|
||||
function ()
|
||||
{
|
||||
"use strict";
|
||||
// Bootstrap popover and tooltip
|
||||
$("[data-toggle='tooltip']").tooltip();
|
||||
|
||||
function handleRun(xhr, timerRefreshLog) {
|
||||
var readyStateStr = {
|
||||
"0": "Request not initialized",
|
||||
"1": "Server connection established",
|
||||
"2": "Response headers received",
|
||||
"3": "Processing request",
|
||||
"4": "Finished and response is ready"
|
||||
};
|
||||
|
||||
$("#console").text("Status: " + xhr.status + " " + xhr.statusText + "\n" + "State: " + readyStateStr[xhr.readyState] + "\n");
|
||||
|
||||
if (xhr.readyState === 4) {
|
||||
// var headers = xhr.getAllResponseHeaders();
|
||||
// $("#console").append(headers);
|
||||
// $("#console").append("See the completed log\n");
|
||||
$("#link_to_bottom").show();
|
||||
clearInterval(timerRefreshLog);
|
||||
refreshLog(xhr); // a last time
|
||||
$("#bt-sync").prop("disabled", false); // back to enable state for next run
|
||||
function is( expected, given, comment )
|
||||
{
|
||||
var message = ": ["
|
||||
+ expected
|
||||
+ "] === ["
|
||||
+ given
|
||||
+ "] "
|
||||
+ comment
|
||||
+ "\n" ;
|
||||
if ( expected === given )
|
||||
{
|
||||
message = "ok " + message ;
|
||||
}
|
||||
else
|
||||
{
|
||||
message = "Nok" + message ;
|
||||
}
|
||||
$("#tests").append( message ) ;
|
||||
}
|
||||
}
|
||||
|
||||
function imapsync() {
|
||||
var querystring = $("#form").serialize();
|
||||
$("#abort").text("\n\n"); // clean abort console
|
||||
$("#output").text("Here comes the log!\n\n");
|
||||
if ("imap.gmail.com" === $("#host1").val()) {
|
||||
querystring = querystring + "&gmail1=on";
|
||||
function last_eta( string )
|
||||
{
|
||||
// return the last occurrence of the substring "ETA: ...\n"
|
||||
// or ""
|
||||
var eta ;
|
||||
var last_found ;
|
||||
|
||||
if ( undefined === string )
|
||||
{
|
||||
return "" ;
|
||||
}
|
||||
|
||||
var eta_re = /ETA:.*\n/g ;
|
||||
|
||||
eta = string.match( eta_re ) ;
|
||||
if ( eta )
|
||||
{
|
||||
last_found = eta[eta.length -1 ] ;
|
||||
return last_found ;
|
||||
}
|
||||
else
|
||||
{
|
||||
return "" ;
|
||||
}
|
||||
}
|
||||
if ("imap.gmail.com" === $("#host2").val()) {
|
||||
querystring = querystring + "&gmail2=on";
|
||||
|
||||
function tests_last_eta()
|
||||
{
|
||||
is( "", last_eta( ), "last_eta: no args => empty string" ) ;
|
||||
is( "", last_eta( "" ), "last_eta: empty => empty string" ) ;
|
||||
is( "", last_eta( "ETA" ), "last_eta: ETA => empty string" ) ;
|
||||
is( "", last_eta( "ETA: but no CR" ),
|
||||
"last_eta: ETA: but no CR => empty string" ) ;
|
||||
|
||||
is(
|
||||
"ETA: with CR\n",
|
||||
last_eta( "Blabla ETA: with CR\n" ),
|
||||
"last_eta: ETA: with CR => ETA: with CR"
|
||||
) ;
|
||||
|
||||
is(
|
||||
"ETA: 2 with CR\n",
|
||||
last_eta( "Blabla ETA: 1 with CR\nBlabla ETA: 2 with CR\n" ),
|
||||
"last_eta: several ETA: with CR => ETA: 2 with CR"
|
||||
) ;
|
||||
}
|
||||
var xhr;
|
||||
xhr = new XMLHttpRequest();
|
||||
var timerRefreshLog = setInterval(function () {
|
||||
refreshLog(xhr);
|
||||
}, 5000);
|
||||
xhr.onreadystatechange = function () {
|
||||
handleRun(xhr, timerRefreshLog);
|
||||
};
|
||||
xhr.open("POST", "/cgi-bin/imapsync", true);
|
||||
xhr.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
|
||||
xhr.send(querystring);
|
||||
}
|
||||
|
||||
|
||||
function handleAbort(xhr) {
|
||||
|
||||
$("#abort").text("Status: " + xhr.status + " " + xhr.statusText + "\n" + "State: " + readyStateStr[xhr.readyState] + "\n\n");
|
||||
|
||||
if (xhr.readyState === 4) {
|
||||
$("#abort").append(xhr.responseText);
|
||||
$("#bt-sync").prop("disabled", false);
|
||||
$("#bt-abort").prop("disabled", false); // back for next abort
|
||||
function refreshLog(xhr)
|
||||
{
|
||||
var slice_length ;
|
||||
$("#output").text(xhr.responseText) ;
|
||||
if (xhr.readyState === 4) {
|
||||
slice_length = -2400 ;
|
||||
}
|
||||
else
|
||||
{
|
||||
slice_length = -240 ;
|
||||
}
|
||||
$("#progress").text( last_eta( xhr.responseText.slice( slice_length ) ) ) ;
|
||||
}
|
||||
}
|
||||
|
||||
function abort() {
|
||||
var querystring = $("#form").serialize() + "&abort=on";
|
||||
var xhr;
|
||||
xhr = new XMLHttpRequest();
|
||||
xhr.onreadystatechange = function () {
|
||||
handleAbort(xhr);
|
||||
};
|
||||
xhr.open("POST", "/cgi-bin/imapsync", true);
|
||||
xhr.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
|
||||
xhr.send(querystring);
|
||||
}
|
||||
|
||||
|
||||
// in case of a manual refresh, start
|
||||
$("#bt-sync").prop("disabled", false);
|
||||
$("#bt-abort").prop("disabled", false);
|
||||
$("#link_to_bottom").hide();
|
||||
|
||||
$("#bt-sync").click(function () {
|
||||
$("#bt-sync").prop("disabled", true);
|
||||
$("#bt-abort").prop("disabled", false);
|
||||
$("#link_to_bottom").hide();
|
||||
imapsync();
|
||||
});
|
||||
function handleRun(xhr, timerRefreshLog)
|
||||
{
|
||||
|
||||
$("#bt-abort").click(function () {
|
||||
$("#bt-sync").prop("disabled", true);
|
||||
$("#bt-abort").prop("disabled", true);
|
||||
abort();
|
||||
});
|
||||
$("#console").text("Status: " + xhr.status + " " + xhr.statusText + "\n" + "State: " + readyStateStr[xhr.readyState] + "\n") ;
|
||||
|
||||
});
|
||||
if (xhr.readyState === 4) {
|
||||
// var headers = xhr.getAllResponseHeaders();
|
||||
// $("#console").append(headers);
|
||||
// $("#console").append("See the completed log\n");
|
||||
$("#link_to_bottom").show();
|
||||
clearInterval(timerRefreshLog);
|
||||
refreshLog(xhr); // a last time
|
||||
$("#bt-sync").prop("disabled", false); // back to enable state for next run
|
||||
}
|
||||
}
|
||||
|
||||
function imapsync()
|
||||
{
|
||||
var querystring = $("#form").serialize();
|
||||
$("#abort").text("\n\n"); // clean abort console
|
||||
$("#output").text("Here comes the log!\n\n");
|
||||
|
||||
if ( "imap.gmail.com" === $("#host1").val() )
|
||||
{
|
||||
querystring = querystring + "&gmail1=on";
|
||||
}
|
||||
if ( "imap.gmail.com" === $("#host2").val() )
|
||||
{
|
||||
querystring = querystring + "&gmail2=on";
|
||||
}
|
||||
|
||||
var xhr;
|
||||
xhr = new XMLHttpRequest();
|
||||
var timerRefreshLog = setInterval(
|
||||
function ()
|
||||
{
|
||||
refreshLog(xhr);
|
||||
}, 5000 ) ;
|
||||
xhr.onreadystatechange = function ()
|
||||
{
|
||||
handleRun(xhr, timerRefreshLog);
|
||||
};
|
||||
xhr.open("POST", "/cgi-bin/imapsync", true);
|
||||
xhr.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
|
||||
xhr.send(querystring);
|
||||
}
|
||||
|
||||
|
||||
function handleAbort(xhr)
|
||||
{
|
||||
|
||||
$("#abort").text("Status: " + xhr.status + " " + xhr.statusText + "\n" + "State: " + readyStateStr[xhr.readyState] + "\n\n");
|
||||
|
||||
if (xhr.readyState === 4)
|
||||
{
|
||||
$("#abort").append(xhr.responseText);
|
||||
$("#bt-sync").prop("disabled", false);
|
||||
$("#bt-abort").prop("disabled", false); // back for next abort
|
||||
}
|
||||
}
|
||||
|
||||
function abort()
|
||||
{
|
||||
var querystring = $("#form").serialize() + "&abort=on";
|
||||
var xhr;
|
||||
xhr = new XMLHttpRequest();
|
||||
xhr.onreadystatechange = function ()
|
||||
{
|
||||
handleAbort(xhr);
|
||||
};
|
||||
xhr.open("POST", "/cgi-bin/imapsync", true);
|
||||
xhr.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
|
||||
xhr.send(querystring);
|
||||
}
|
||||
|
||||
function store( id )
|
||||
{
|
||||
var stored ;
|
||||
$( "#tests" ).append( "Eco: " + id + " type is " + $( id ).attr( "type" ) + "\n" ) ;
|
||||
if ( "text" === $( id ).attr( "type" ) || "password" === $( id ).attr( "type" ) )
|
||||
{
|
||||
localStorage.setItem( id, $(id).val() ) ;
|
||||
stored = $(id).val() ;
|
||||
}
|
||||
else if ( "checkbox" === $( id ).attr( "type" ) )
|
||||
{
|
||||
$( "#tests" ).append( "Eco: " + id + " checked is " + $( id )[0].checked + "\n" ) ;
|
||||
localStorage.setItem( id, $( id )[0].checked ) ;
|
||||
stored = $( id )[0].checked ;
|
||||
}
|
||||
return stored ;
|
||||
}
|
||||
|
||||
function retrieve( id )
|
||||
{
|
||||
var retrieved ;
|
||||
$( "#tests" ).append( "Eco: " + id + " type is " + $( id ).attr( "type" ) + " length is " + $( id ).length + "\n" ) ;
|
||||
if ( "text" === $( id ).attr( "type" ) || "password" === $( id ).attr( "type" ) )
|
||||
{
|
||||
$( id ).val( localStorage.getItem( id ) ) ;
|
||||
retrieved = $( id ).val() ;
|
||||
}
|
||||
else if ( "checkbox" === $( id ).attr( "type" ) )
|
||||
{
|
||||
$( "#tests" ).append( "Eco: " + id + " getItem is " + localStorage.getItem( id ) + "\n" ) ;
|
||||
$( id )[0].checked = JSON.parse( localStorage.getItem( id ) ) ;
|
||||
retrieved = $( id )[0].checked ;
|
||||
}
|
||||
return retrieved ;
|
||||
}
|
||||
|
||||
function tests_store_retrieve()
|
||||
{
|
||||
if ( $("#tests").length !== 0 )
|
||||
{
|
||||
is( 1, 1, "one equals one" ) ;
|
||||
// isnot( 0, 1, "zero differs one" ) ;
|
||||
|
||||
// no exist
|
||||
is( undefined, store( "#test_noexists" ), "store: #test_noexists" ) ;
|
||||
is( undefined, retrieve( "#test_noexists" ), "retrieve: #test_noexists" ) ;
|
||||
is( undefined, retrieve( "#test_noexists2" ), "retrieve: #test_noexists2" ) ;
|
||||
|
||||
// input text
|
||||
$("#test_text" ).val( "foo" ) ;
|
||||
is( "foo", $("#test_text" ).val( ), "#test_text val = foo" ) ;
|
||||
is( "foo", store( "#test_text" ), "store: #test_text" ) ;
|
||||
$("#test_text" ).val( "bar" ) ;
|
||||
is( "bar", $("#test_text" ).val( ), "#test_text val = bar" ) ;
|
||||
is( "foo", retrieve( "#test_text" ), "retrieve: #test_text = foo" ) ;
|
||||
is( "foo", $("#test_text" ).val( ), "#test_text val = foo" ) ;
|
||||
|
||||
|
||||
// input check button
|
||||
$( "#test_checkbox" ).prop( "checked", true );
|
||||
is( true, store( "#test_checkbox" ), "store: #test_checkbox checked" ) ;
|
||||
|
||||
$( "#test_checkbox" ).prop( "checked", false );
|
||||
is( true, retrieve( "#test_checkbox" ), "retrieve: #test_checkbox = true" ) ;
|
||||
|
||||
$( "#test_checkbox" ).prop( "checked", false );
|
||||
is( false, store( "#test_checkbox" ), "store: #test_checkbox not checked" ) ;
|
||||
$( "#test_checkbox" ).prop( "checked", true );
|
||||
is( false, retrieve( "#test_checkbox" ), "retrieve: #test_checkbox = false" ) ;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
function store_form()
|
||||
{
|
||||
if ( Storage !== "undefined")
|
||||
{
|
||||
// Code for localStorage.
|
||||
store("#user1") ;
|
||||
store("#password1") ;
|
||||
store("#host1") ;
|
||||
store("#subfolder1") ;
|
||||
store("#showpassword1") ;
|
||||
|
||||
store("#user2") ;
|
||||
store("#password2") ;
|
||||
store("#host2") ;
|
||||
store("#subfolder2") ;
|
||||
store("#showpassword2") ;
|
||||
|
||||
store("#dry") ;
|
||||
store("#justlogin") ;
|
||||
store("#justfolders") ;
|
||||
store("#justfoldersizes") ;
|
||||
|
||||
localStorage.account1_background_color = $("#account1").css("background-color") ;
|
||||
localStorage.account2_background_color = $("#account2").css("background-color") ;
|
||||
}
|
||||
}
|
||||
|
||||
function show_extra_if_needed()
|
||||
{
|
||||
if ( $("#subfolder1").length && $("#subfolder1").val().length > 0 )
|
||||
{
|
||||
$(".extra_param").show() ;
|
||||
}
|
||||
if ( $("#subfolder2").length && $("#subfolder2").val().length > 0 )
|
||||
{
|
||||
$(".extra_param").show() ;
|
||||
}
|
||||
}
|
||||
|
||||
function retrieve_form()
|
||||
{
|
||||
if ( Storage !== "undefined" )
|
||||
{
|
||||
// Code for localStorage.
|
||||
retrieve( "#user1" ) ;
|
||||
retrieve( "#password1" ) ;
|
||||
// retrieve("#showpassword1") ;
|
||||
retrieve( "#host1" ) ;
|
||||
retrieve( "#subfolder1" ) ;
|
||||
|
||||
retrieve( "#user2" ) ;
|
||||
retrieve( "#password2" ) ;
|
||||
// retrieve("#showpassword2") ;
|
||||
retrieve( "#host2" ) ;
|
||||
retrieve( "#subfolder2" ) ;
|
||||
|
||||
retrieve( "#dry" ) ;
|
||||
retrieve( "#justlogin" ) ;
|
||||
retrieve( "#justfolders" ) ;
|
||||
retrieve( "#justfoldersizes" ) ;
|
||||
|
||||
// In case
|
||||
// localStorage.removeItem( "account1_background_color" ) ;
|
||||
// localStorage.removeItem( "account2_background_color" ) ;
|
||||
|
||||
if ( localStorage.account1_background_color )
|
||||
{
|
||||
$("#account1").css("background-color", localStorage.account1_background_color ) ;
|
||||
}
|
||||
if ( localStorage.account2_background_color )
|
||||
{
|
||||
$("#account2").css("background-color", localStorage.account2_background_color ) ;
|
||||
}
|
||||
|
||||
// Show the extra parameters if they are not empty because it would be dangerous
|
||||
// to retrieve them without knowing
|
||||
show_extra_if_needed() ;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
function showpassword( id, button )
|
||||
{
|
||||
var x = document.getElementById( id );
|
||||
if ( button.checked )
|
||||
{
|
||||
x.type = "text";
|
||||
} else {
|
||||
x.type = "password";
|
||||
}
|
||||
}
|
||||
|
||||
function init()
|
||||
{
|
||||
// in case of a manual refresh, start with
|
||||
$("#bt-sync").prop("disabled", false);
|
||||
$("#bt-abort").prop("disabled", false);
|
||||
$("#link_to_bottom").hide();
|
||||
retrieve_form();
|
||||
|
||||
$("#showpassword1").click(
|
||||
function ()
|
||||
{
|
||||
// does not change jslint report...
|
||||
/*jshint validthis: true */
|
||||
var button = this ;
|
||||
showpassword( "password1", button ) ;
|
||||
}
|
||||
);
|
||||
|
||||
|
||||
$("#showpassword2").click(
|
||||
function ()
|
||||
{
|
||||
var button = this ;
|
||||
showpassword( "password2", button ) ;
|
||||
}
|
||||
);
|
||||
|
||||
|
||||
$("#bt-sync").click(
|
||||
function ()
|
||||
{
|
||||
$("#bt-sync").prop("disabled", true);
|
||||
$("#bt-abort").prop("disabled", false);
|
||||
$("#link_to_bottom").hide();
|
||||
store_form();
|
||||
imapsync();
|
||||
}
|
||||
);
|
||||
|
||||
$("#bt-abort").click(
|
||||
function ()
|
||||
{
|
||||
$("#bt-sync").prop("disabled", true);
|
||||
$("#bt-abort").prop("disabled", true);
|
||||
abort();
|
||||
}
|
||||
);
|
||||
|
||||
|
||||
$.fn.swapWith = function(to)
|
||||
{
|
||||
var temp = $(to).val();
|
||||
$(to).val($(this).val());
|
||||
$(this).val(temp);
|
||||
};
|
||||
|
||||
|
||||
$("#swap").click(
|
||||
function()
|
||||
{
|
||||
// swaping colors can't use swapWith()
|
||||
var temp1 = $("#account1").css("background-color") ;
|
||||
var temp2 = $("#account2").css("background-color") ;
|
||||
$("#account1").css("background-color", temp2 );
|
||||
$("#account2").css("background-color", temp1 );
|
||||
|
||||
$("#user1").swapWith("#user2");
|
||||
$("#password1").swapWith("#password2");
|
||||
$("#host1").swapWith("#host2");
|
||||
$("#subfolder1").swapWith("#subfolder2");
|
||||
|
||||
var temp = $("#showpassword1")[0].checked ;
|
||||
$("#showpassword1")[0].checked = $("#showpassword2")[0].checked ;
|
||||
$("#showpassword2")[0].checked = temp ;
|
||||
showpassword( "password1", $("#showpassword1")[0] ) ;
|
||||
showpassword( "password2", $("#showpassword2")[0] ) ;
|
||||
}
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
function progress_bar_update( string )
|
||||
{
|
||||
//
|
||||
return ;
|
||||
}
|
||||
|
||||
|
||||
|
||||
function tests()
|
||||
{
|
||||
if ( $("#tests").length !== 0 )
|
||||
{
|
||||
tests_store_retrieve() ;
|
||||
tests_last_eta() ;
|
||||
}
|
||||
}
|
||||
|
||||
init( ) ;
|
||||
tests( ) ;
|
||||
|
||||
}
|
||||
|
||||
);
|
||||
|
||||
|
|
159
X/imapsync_form_1.3.js
Executable file
159
X/imapsync_form_1.3.js
Executable file
|
@ -0,0 +1,159 @@
|
|||
|
||||
// $Id: imapsync_form.js,v 1.3 2019/03/18 19:21:16 gilles Exp gilles $
|
||||
|
||||
/*jslint browser: true*/ /*global $*/
|
||||
$(document).ready(function () {
|
||||
"use strict";
|
||||
// Bootstrap popover and tooltip
|
||||
$("[data-toggle='tooltip']").tooltip();
|
||||
|
||||
var readyStateStr = {
|
||||
"0": "Request not initialized",
|
||||
"1": "Server connection established",
|
||||
"2": "Response headers received",
|
||||
"3": "Processing request",
|
||||
"4": "Finished and response is ready"
|
||||
};
|
||||
|
||||
function refreshLog(xhr) {
|
||||
$("#output").html(xhr.responseText);
|
||||
}
|
||||
|
||||
function handleRun(xhr, timerRefreshLog) {
|
||||
|
||||
$("#console").text("Status: " + xhr.status + " " + xhr.statusText + "\n" + "State: " + readyStateStr[xhr.readyState] + "\n");
|
||||
|
||||
if (xhr.readyState === 4) {
|
||||
// var headers = xhr.getAllResponseHeaders();
|
||||
// $("#console").append(headers);
|
||||
// $("#console").append("See the completed log\n");
|
||||
$("#link_to_bottom").show();
|
||||
clearInterval(timerRefreshLog);
|
||||
refreshLog(xhr); // a last time
|
||||
$("#bt-sync").prop("disabled", false); // back to enable state for next run
|
||||
}
|
||||
}
|
||||
|
||||
function imapsync() {
|
||||
var querystring = $("#form").serialize();
|
||||
$("#abort").text("\n\n"); // clean abort console
|
||||
$("#output").text("Here comes the log!\n\n");
|
||||
if ("imap.gmail.com" === $("#host1").val()) {
|
||||
querystring = querystring + "&gmail1=on";
|
||||
}
|
||||
if ("imap.gmail.com" === $("#host2").val()) {
|
||||
querystring = querystring + "&gmail2=on";
|
||||
}
|
||||
var xhr;
|
||||
xhr = new XMLHttpRequest();
|
||||
var timerRefreshLog = setInterval(function () {
|
||||
refreshLog(xhr);
|
||||
}, 5000);
|
||||
xhr.onreadystatechange = function () {
|
||||
handleRun(xhr, timerRefreshLog);
|
||||
};
|
||||
xhr.open("POST", "/cgi-bin/imapsync", true);
|
||||
xhr.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
|
||||
xhr.send(querystring);
|
||||
}
|
||||
|
||||
|
||||
function handleAbort(xhr) {
|
||||
|
||||
$("#abort").text("Status: " + xhr.status + " " + xhr.statusText + "\n" + "State: " + readyStateStr[xhr.readyState] + "\n\n");
|
||||
|
||||
if (xhr.readyState === 4) {
|
||||
$("#abort").append(xhr.responseText);
|
||||
$("#bt-sync").prop("disabled", false);
|
||||
$("#bt-abort").prop("disabled", false); // back for next abort
|
||||
}
|
||||
}
|
||||
|
||||
function abort() {
|
||||
var querystring = $("#form").serialize() + "&abort=on";
|
||||
var xhr;
|
||||
xhr = new XMLHttpRequest();
|
||||
xhr.onreadystatechange = function () {
|
||||
handleAbort(xhr);
|
||||
};
|
||||
xhr.open("POST", "/cgi-bin/imapsync", true);
|
||||
xhr.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
|
||||
xhr.send(querystring);
|
||||
}
|
||||
|
||||
function store_form() {
|
||||
if (typeof(Storage) !== "undefined") {
|
||||
// Code for localStorage.
|
||||
localStorage.user1 = $("#user1").val();
|
||||
localStorage.password1 = $("#password1").val();
|
||||
localStorage.host1 = $("#host1").val();
|
||||
|
||||
localStorage.user2 = $("#user2").val();
|
||||
localStorage.password2 = $("#password2").val();
|
||||
localStorage.host2 = $("#host2").val();
|
||||
} else {
|
||||
// Sorry! No Web Storage support...
|
||||
}
|
||||
}
|
||||
|
||||
function retrieve_form() {
|
||||
if (typeof(Storage) !== "undefined") {
|
||||
// Code for localStorage.
|
||||
$("#user1").val(localStorage.user1);
|
||||
$("#password1").val(localStorage.password1);
|
||||
$("#host1").val(localStorage.host1);
|
||||
$("#user2").val(localStorage.user2);
|
||||
$("#password2").val(localStorage.password2);
|
||||
$("#host2").val(localStorage.host2);
|
||||
} else {
|
||||
// Sorry! No Web Storage support...
|
||||
}
|
||||
}
|
||||
|
||||
function showpassword() {
|
||||
}
|
||||
|
||||
// in case of a manual refresh, start with
|
||||
$("#bt-sync").prop("disabled", false);
|
||||
$("#bt-abort").prop("disabled", false);
|
||||
$("#link_to_bottom").hide();
|
||||
retrieve_form();
|
||||
|
||||
// Well I should write function showpassword() body and use it
|
||||
// I'm just dumb in js and jQuery
|
||||
$("#showpassword1").click(function () {
|
||||
var x = document.getElementById("password1");
|
||||
if (x.type === "password") {
|
||||
x.type = "text";
|
||||
} else {
|
||||
x.type = "password";
|
||||
}
|
||||
});
|
||||
|
||||
$("#showpassword2").click(function () {
|
||||
var x = document.getElementById("password2");
|
||||
if (x.type === "password") {
|
||||
x.type = "text";
|
||||
} else {
|
||||
x.type = "password";
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
|
||||
$("#bt-sync").click(function () {
|
||||
$("#bt-sync").prop("disabled", true);
|
||||
$("#bt-abort").prop("disabled", false);
|
||||
$("#link_to_bottom").hide();
|
||||
store_form();
|
||||
imapsync();
|
||||
});
|
||||
|
||||
$("#bt-abort").click(function () {
|
||||
$("#bt-sync").prop("disabled", true);
|
||||
$("#bt-abort").prop("disabled", true);
|
||||
abort();
|
||||
});
|
||||
|
||||
});
|
||||
|
228
X/imapsync_form_1.4.js
Executable file
228
X/imapsync_form_1.4.js
Executable file
|
@ -0,0 +1,228 @@
|
|||
|
||||
// $Id: imapsync_form.js,v 1.4 2019/04/28 03:02:37 gilles Exp $
|
||||
|
||||
/*jslint browser: true*/ /*global $*/
|
||||
$(document).ready(function () {
|
||||
"use strict";
|
||||
// Bootstrap popover and tooltip
|
||||
$("[data-toggle='tooltip']").tooltip();
|
||||
|
||||
var readyStateStr = {
|
||||
"0": "Request not initialized",
|
||||
"1": "Server connection established",
|
||||
"2": "Response headers received",
|
||||
"3": "Processing request",
|
||||
"4": "Finished and response is ready"
|
||||
};
|
||||
|
||||
function refreshLog(xhr) {
|
||||
$("#output").html(xhr.responseText);
|
||||
}
|
||||
|
||||
function handleRun(xhr, timerRefreshLog) {
|
||||
|
||||
$("#console").text("Status: " + xhr.status + " " + xhr.statusText + "\n" + "State: " + readyStateStr[xhr.readyState] + "\n");
|
||||
|
||||
if (xhr.readyState === 4) {
|
||||
// var headers = xhr.getAllResponseHeaders();
|
||||
// $("#console").append(headers);
|
||||
// $("#console").append("See the completed log\n");
|
||||
$("#link_to_bottom").show();
|
||||
clearInterval(timerRefreshLog);
|
||||
refreshLog(xhr); // a last time
|
||||
$("#bt-sync").prop("disabled", false); // back to enable state for next run
|
||||
}
|
||||
}
|
||||
|
||||
function imapsync() {
|
||||
var querystring = $("#form").serialize();
|
||||
$("#abort").text("\n\n"); // clean abort console
|
||||
$("#output").text("Here comes the log!\n\n");
|
||||
if ("imap.gmail.com" === $("#host1").val()) {
|
||||
querystring = querystring + "&gmail1=on";
|
||||
}
|
||||
if ("imap.gmail.com" === $("#host2").val()) {
|
||||
querystring = querystring + "&gmail2=on";
|
||||
}
|
||||
var xhr;
|
||||
xhr = new XMLHttpRequest();
|
||||
var timerRefreshLog = setInterval(function () {
|
||||
refreshLog(xhr);
|
||||
}, 5000);
|
||||
xhr.onreadystatechange = function () {
|
||||
handleRun(xhr, timerRefreshLog);
|
||||
};
|
||||
xhr.open("POST", "/cgi-bin/imapsync", true);
|
||||
xhr.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
|
||||
xhr.send(querystring);
|
||||
}
|
||||
|
||||
|
||||
function handleAbort(xhr) {
|
||||
|
||||
$("#abort").text("Status: " + xhr.status + " " + xhr.statusText + "\n" + "State: " + readyStateStr[xhr.readyState] + "\n\n");
|
||||
|
||||
if (xhr.readyState === 4) {
|
||||
$("#abort").append(xhr.responseText);
|
||||
$("#bt-sync").prop("disabled", false);
|
||||
$("#bt-abort").prop("disabled", false); // back for next abort
|
||||
}
|
||||
}
|
||||
|
||||
function abort() {
|
||||
var querystring = $("#form").serialize() + "&abort=on";
|
||||
var xhr;
|
||||
xhr = new XMLHttpRequest();
|
||||
xhr.onreadystatechange = function () {
|
||||
handleAbort(xhr);
|
||||
};
|
||||
xhr.open("POST", "/cgi-bin/imapsync", true);
|
||||
xhr.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
|
||||
xhr.send(querystring);
|
||||
}
|
||||
|
||||
function store_form() {
|
||||
if (typeof(Storage) !== "undefined") {
|
||||
// Code for localStorage.
|
||||
localStorage.user1 = $("#user1").val();
|
||||
localStorage.password1 = $("#password1").val();
|
||||
localStorage.host1 = $("#host1").val();
|
||||
localStorage.subfolder1 = $("#subfolder1").val();
|
||||
localStorage.showpassword1 = $("#showpassword1")[0].checked ;
|
||||
|
||||
//
|
||||
localStorage.account1_background_color = $("#account1").css("background-color") ;
|
||||
|
||||
localStorage.user2 = $("#user2").val();
|
||||
localStorage.password2 = $("#password2").val();
|
||||
localStorage.host2 = $("#host2").val();
|
||||
localStorage.subfolder2 = $("#subfolder2").val();
|
||||
localStorage.showpassword2 = $("#showpassword2")[0].checked ;
|
||||
|
||||
// alert( $("#dry")[0].checked ) ;
|
||||
localStorage.dry = $("#dry")[0].checked ;
|
||||
localStorage.justlogin = $("#justlogin")[0].checked ;
|
||||
localStorage.justfolders = $("#justfolders")[0].checked ;
|
||||
localStorage.justfoldersizes = $("#justfoldersizes")[0].checked ;
|
||||
|
||||
localStorage.account2_background_color = $("#account2").css("background-color") ;
|
||||
|
||||
} else {
|
||||
// Sorry! No Web Storage support...
|
||||
}
|
||||
}
|
||||
|
||||
function retrieve_form() {
|
||||
if (typeof(Storage) !== "undefined")
|
||||
{
|
||||
// Code for localStorage.
|
||||
$("#user1").val(localStorage.user1);
|
||||
$("#password1").val(localStorage.password1);
|
||||
// $("#showpassword1")[0].checked = JSON.parse(localStorage.showpassword1);
|
||||
$("#host1").val(localStorage.host1);
|
||||
$("#subfolder1").val(localStorage.subfolder1);
|
||||
|
||||
$("#user2").val(localStorage.user2);
|
||||
$("#password2").val(localStorage.password2);
|
||||
// $("#showpassword2")[0].checked = JSON.parse(localStorage.showpassword2);
|
||||
$("#host2").val(localStorage.host2);
|
||||
$("#subfolder2").val(localStorage.subfolder2);
|
||||
|
||||
|
||||
$("#dry")[0].checked = JSON.parse(localStorage.dry || false );
|
||||
$("#justlogin")[0].checked = JSON.parse(localStorage.justlogin || false );
|
||||
$("#justfolders")[0].checked = JSON.parse(localStorage.justfolders || false );
|
||||
$("#justfoldersizes")[0].checked = JSON.parse(localStorage.justfoldersizes || false );
|
||||
|
||||
// In case
|
||||
// localStorage.removeItem( "account1_background_color" ) ;
|
||||
// localStorage.removeItem( "account2_background_color" ) ;
|
||||
|
||||
if ( localStorage.account1_background_color )
|
||||
{
|
||||
$("#account1").css("background-color", localStorage.account1_background_color ) ;
|
||||
}
|
||||
if ( localStorage.account2_background_color )
|
||||
{
|
||||
$("#account2").css("background-color", localStorage.account2_background_color ) ;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
// Sorry! No Web Storage support...
|
||||
}
|
||||
}
|
||||
|
||||
function showpassword() {
|
||||
}
|
||||
|
||||
// in case of a manual refresh, start with
|
||||
$("#bt-sync").prop("disabled", false);
|
||||
$("#bt-abort").prop("disabled", false);
|
||||
$("#link_to_bottom").hide();
|
||||
retrieve_form();
|
||||
|
||||
// Well I should write function showpassword() body and use it
|
||||
// I'm just dumb in js and jQuery
|
||||
$("#showpassword1").click(function () {
|
||||
var x = document.getElementById("password1");
|
||||
if (x.type === "password" && this.checked ) {
|
||||
x.type = "text";
|
||||
} else {
|
||||
x.type = "password";
|
||||
}
|
||||
});
|
||||
|
||||
$("#showpassword2").click(function () {
|
||||
var x = document.getElementById("password2");
|
||||
if (x.type === "password" && this.checked ) {
|
||||
x.type = "text";
|
||||
} else {
|
||||
x.type = "password";
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
|
||||
$("#bt-sync").click(function () {
|
||||
$("#bt-sync").prop("disabled", true);
|
||||
$("#bt-abort").prop("disabled", false);
|
||||
$("#link_to_bottom").hide();
|
||||
store_form();
|
||||
imapsync();
|
||||
});
|
||||
|
||||
$("#bt-abort").click(function () {
|
||||
$("#bt-sync").prop("disabled", true);
|
||||
$("#bt-abort").prop("disabled", true);
|
||||
abort();
|
||||
});
|
||||
|
||||
|
||||
jQuery.fn.swapWith = function(to) {
|
||||
var temp = $(to).val();
|
||||
$(to).val($(this).val());
|
||||
$(this).val(temp);
|
||||
};
|
||||
|
||||
|
||||
|
||||
$("#swap").click(function(){
|
||||
$("#user1").swapWith("#user2");
|
||||
$("#password1").swapWith("#password2");
|
||||
$("#host1").swapWith("#host2");
|
||||
$("#subfolder1").swapWith("#subfolder2");
|
||||
|
||||
var temp = $("#account1").css("background-color") ;
|
||||
$("#account1").css("background-color", $("#account2").css("background-color") ) ;
|
||||
$("#account2").css("background-color", temp ) ;
|
||||
|
||||
});
|
||||
|
||||
// End of
|
||||
|
||||
|
||||
});
|
||||
|
344
X/imapsync_form_1.69.html
Executable file
344
X/imapsync_form_1.69.html
Executable file
|
@ -0,0 +1,344 @@
|
|||
<!DOCTYPE html>
|
||||
<!-- $Id: imapsync_form.html,v 1.69 2019/03/31 22:25:15 gilles Exp $ -->
|
||||
|
||||
<html lang="en" id="top">
|
||||
|
||||
<head>
|
||||
<title>Imapsync online</title>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
|
||||
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css"
|
||||
integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">
|
||||
|
||||
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap-theme.min.css"
|
||||
integrity="sha384-rHyoN1iRsVXV4nD0JutlnGaslCJuC7uwjduW9SVrLvRYooPp2bWYgmgJQIXwl/Sp" crossorigin="anonymous">
|
||||
|
||||
<link rel="stylesheet" href="imapsync_form.css">
|
||||
|
||||
<link rel="license" href="https://imapsync.lamiral.info/NOLIMIT">
|
||||
|
||||
|
||||
<noscript>
|
||||
<style>
|
||||
.scripton {display:none;}
|
||||
</style>
|
||||
</noscript>
|
||||
|
||||
</head>
|
||||
|
||||
<body>
|
||||
|
||||
|
||||
<div class="container-fluid" >
|
||||
|
||||
<div class="row">
|
||||
<div class="text-center">
|
||||
<a href="https://imapsync.lamiral.info/">
|
||||
<img alt="Imapsync home" title="Imapsync home page" src="https://imapsync.lamiral.info/X/logo_imapsync_Xn.png" height="38" width="60">
|
||||
</a>
|
||||
<a href="#top" title="Top of the page" class="btn btn-info " role="button">Top</a>
|
||||
<!-- <a href="#payment" class="btn btn-success" data-toggle="collapse">Pricing</a> -->
|
||||
<!-- <a href="#buttons" class="btn btn-info scripton" role="button">Consoles</a> -->
|
||||
<a href="#bottom" title="Bottom of the page" class="btn btn-info active" role="button">Bottom</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<h1 class="text-center">Imapsync online</h1>
|
||||
|
||||
<p class="text-center"> <strong>Copy</strong>/synchronize a <strong>complete</strong> mailbox to another, without <strong>duplicates!</strong></p>
|
||||
|
||||
<!-- Paypal part start
|
||||
new: NDGMR6TLFZ926
|
||||
old: H2YTURNFT4XT4
|
||||
-->
|
||||
|
||||
<!-- A button above the pricing form, not very beautiful...
|
||||
I should give it a try anyway because nearly no one buy this service...
|
||||
<div class="text-center">
|
||||
<a href="#payment" class="btn btn-warning btn-lg" data-toggle="collapse">Pricing</a>
|
||||
</div>
|
||||
-->
|
||||
|
||||
<!-- the "in" makes the form not collapsed by default
|
||||
Remove the in in order to mask the pricing section
|
||||
<div id="payment" class="well text-center collapse in" > -->
|
||||
<div id="payment" class="well text-center collapse" >
|
||||
<p class="lead">Pay by usage type</p>
|
||||
<form action="https://www.paypal.com/cgi-bin/webscr" method="post" target="_blank">
|
||||
<input type="hidden" name="cmd" value="_s-xclick" />
|
||||
<input type="hidden" name="hosted_button_id" value="H2YTURNFT4XT4" />
|
||||
<input type="hidden" name="on0" value="imapsync choice" />
|
||||
<fieldset>
|
||||
<!--
|
||||
<label data-toggle="tooltip" data-placement="top" title="Fair enough"
|
||||
class="radio-inline"><input type="radio" name="os0" value="Tiny" > €1,00 </label>
|
||||
-->
|
||||
<label data-toggle="tooltip" data-placement="top" title="A big mailbox"
|
||||
class="radio-inline"><input type="radio" name="os0" value="Small" > €6,00 </label>
|
||||
<label data-toggle="tooltip" data-placement="top" title="Several mailboxes to migrate"
|
||||
class="radio-inline"><input type="radio" name="os0" value="Normal" checked > €59,00 </label>
|
||||
<!--
|
||||
<label data-toggle="tooltip" data-placement="top" title="Tons of gigabytes to copy"
|
||||
class="radio-inline"><input type="radio" name="os0" value="High" > €125,00 </label>
|
||||
-->
|
||||
<br>
|
||||
<input type="hidden" name="currency_code" value="EUR" />
|
||||
<input type="image" src="https://www.paypalobjects.com/en_US/i/btn/btn_buynowCC_LG.gif" name="submit" alt="PayPal - A safe, easy way to pay online!" />
|
||||
</fieldset>
|
||||
<p>
|
||||
<strong>30-day money back guarantee!</strong> <br>
|
||||
<em>No question nor condition to get a refund, really, just request it and you'll sure get a refund!</em>
|
||||
</p>
|
||||
</form>
|
||||
</div>
|
||||
<!-- Paypal part end -->
|
||||
|
||||
|
||||
<form id="form" action="/cgi-bin/imapsync" method="post" autocomplete="on">
|
||||
<div class="row">
|
||||
<div id="account1" class="col-md-6" >
|
||||
<fieldset>
|
||||
<legend class="text-center h2">IMAP source mailbox</legend>
|
||||
|
||||
<label for="user1">Login</label>
|
||||
<div class="input-group form-group">
|
||||
<span class="input-group-addon"><i class="glyphicon glyphicon-user"> </i></span>
|
||||
<input
|
||||
data-toggle="tooltip" data-placement="bottom" title="It is usually an email address or its left part before @"
|
||||
type="text" class="form-control input-lg" id="user1" name="user1" tabindex="1"
|
||||
placeholder="Enter login name">
|
||||
</div>
|
||||
|
||||
<label for="password1">Password</label>
|
||||
<label class="checkbox-inline">
|
||||
<input type="checkbox" id="showpassword1"> show password
|
||||
</label>
|
||||
<div class="input-group form-group">
|
||||
<span class="input-group-addon"><i class="glyphicon glyphicon-lock"></i></span>
|
||||
<input
|
||||
data-toggle="tooltip" data-placement="bottom" title="Passwords are not stored on the server"
|
||||
type="password" class="form-control input-lg" id="password1" name="password1" tabindex="2"
|
||||
placeholder="Enter password">
|
||||
</div>
|
||||
|
||||
<label for="host1">Server</label>
|
||||
<div class="input-group form-group">
|
||||
<span class="input-group-addon"><i class="glyphicon glyphicon-cloud"></i></span>
|
||||
<input
|
||||
data-toggle="tooltip" data-placement="bottom" title="IMAP transfers are done with encryption if the servers support it."
|
||||
list="servers1" type="text" class="form-control input-lg" id="host1" name="host1" tabindex="3"
|
||||
placeholder="Enter imap source server name or IP address">
|
||||
<datalist id="servers1">
|
||||
<option value="imap.gmail.com">
|
||||
<option value="outlook.office365.com">
|
||||
<option value="imap.mail.yahoo.com">
|
||||
</datalist>
|
||||
</div>
|
||||
|
||||
<!--
|
||||
<div class="form-group" style="padding-bottom: 15px;">
|
||||
<label class="checkbox-inline">
|
||||
<input type="checkbox" id="ssl1" name="ssl1" tabindex="4">-ssl1 (port 993)
|
||||
</label>
|
||||
</div>
|
||||
-->
|
||||
<div>
|
||||
<br>
|
||||
</div>
|
||||
</fieldset>
|
||||
</div>
|
||||
|
||||
|
||||
<div id="account2" class="col-md-6" >
|
||||
<fieldset>
|
||||
<legend class="text-center h2">IMAP destination mailbox</legend>
|
||||
|
||||
<label for="user2">Login</label>
|
||||
<div class="input-group form-group">
|
||||
<span class="input-group-addon"><i class="glyphicon glyphicon-user"></i></span>
|
||||
<input
|
||||
data-toggle="tooltip" data-placement="bottom" title="It is usually an email address or its left part before @"
|
||||
type="text" class="form-control input-lg" id="user2" name="user2" tabindex="6"
|
||||
placeholder="Enter login name">
|
||||
</div>
|
||||
<label for="password2">Password</label>
|
||||
<label class="checkbox-inline">
|
||||
<input type="checkbox" id="showpassword2"> show password
|
||||
</label>
|
||||
<div class="input-group form-group">
|
||||
<span class="input-group-addon"><i class="glyphicon glyphicon-lock"></i></span>
|
||||
<input
|
||||
data-toggle="tooltip" data-placement="bottom" title="Passwords are not stored on the server"
|
||||
type="password" class="form-control input-lg" id="password2" name="password2" tabindex="7"
|
||||
placeholder="Enter password">
|
||||
</div>
|
||||
|
||||
<label for="host2">Server</label>
|
||||
<div class="input-group form-group">
|
||||
<span class="input-group-addon"><i class="glyphicon glyphicon-cloud"></i></span>
|
||||
<input
|
||||
data-toggle="tooltip" data-placement="bottom" title="IMAP transfers are done with encryption if the servers support it."
|
||||
list="servers2" type="text" class="form-control input-lg" id="host2" name="host2" tabindex="8"
|
||||
placeholder="Enter imap destination server name or IP address">
|
||||
<datalist id="servers2">
|
||||
<option value="imap.gmail.com">
|
||||
<option value="outlook.office365.com">
|
||||
<option value="imap.mail.yahoo.com">
|
||||
</datalist>
|
||||
</div>
|
||||
<!--
|
||||
<div class="form-group" style="padding-bottom: 15px;">
|
||||
<label class="checkbox-inline">
|
||||
<input type="checkbox" id="ssl2" name="ssl2" tabindex="9">-ssl2 (port 993)
|
||||
</label>
|
||||
</div>
|
||||
-->
|
||||
<div>
|
||||
<br>
|
||||
</div>
|
||||
</fieldset>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<input type="hidden" name="automap" value="on">
|
||||
<input type="hidden" name="addheader" value="on">
|
||||
<!-- --#>
|
||||
<input type="hidden" name="simulong" value="360">
|
||||
<#!-- -->
|
||||
<a name="buttons"></a>
|
||||
<hr>
|
||||
|
||||
<!-- Classical button to go to the log only -->
|
||||
<noscript>
|
||||
<button type="submit" class="btn btn-success btn-lg center-block btn-block">Go sync!</button>
|
||||
</noscript>
|
||||
|
||||
<!-- Javascript buttons using xhr -->
|
||||
<div class="row scripton">
|
||||
<div class="col-sm-6 padd0" >
|
||||
<button id="bt-sync" type="button"
|
||||
class="btn btn-success btn-lg center-block btn-block"
|
||||
tabindex="11"
|
||||
data-toggle="tooltip" data-placement="top"
|
||||
title="Launch the sync! You can abort the sync with the red Abort button nearby or by closing the tab/window."
|
||||
>
|
||||
Sync or resync!<br>
|
||||
<span class="glyphicon glyphicon-envelope"></span>
|
||||
<span class="glyphicon glyphicon-arrow-right"></span>
|
||||
<span class="glyphicon glyphicon-envelope"></span>
|
||||
</button>
|
||||
</div>
|
||||
<div class="col-sm-6 padd0" >
|
||||
<button id="bt-abort" type="button"
|
||||
class="btn btn-danger btn-lg center-block btn-block" tabindex="12"
|
||||
data-toggle="tooltip" data-placement="top"
|
||||
title="Abort the sync! You can restart the sync later, no duplicates should happen."
|
||||
>
|
||||
Abort!<br>
|
||||
<span class="glyphicon glyphicon-scissors"></span>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
|
||||
<div class="row scripton" id="consoles">
|
||||
<div class="col-sm-6 well">
|
||||
<h2 class="text-center">Console of imapsync run</h2>
|
||||
<pre id="console">
|
||||
|
||||
|
||||
|
||||
</pre>
|
||||
<a id="link_to_bottom" href="#bottom">Bottom of imapsync log</a>
|
||||
</div>
|
||||
|
||||
<div class="col-sm-6 well">
|
||||
<h2 class="text-center">Console of abort</h2>
|
||||
<pre id="abort">
|
||||
|
||||
|
||||
|
||||
</pre>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<h2 class="text-center scripton">Log of imapsync run</h2>
|
||||
|
||||
<pre id="output" class="scripton">
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
</pre>
|
||||
|
||||
<a name="bottom"></a>
|
||||
<hr>
|
||||
<p class="text-center">
|
||||
Local bandwidth statistics <br>
|
||||
<a href="/vnstat/vnstati.html">
|
||||
<img alt="Local bandwidth statistics" src="/vnstat/vnstat_vs.png" >
|
||||
</a>
|
||||
</p>
|
||||
|
||||
<p class="text-center">Feel free to contact
|
||||
<strong><a href="https://imapsync.lamiral.info/#AUTHOR" target="_blank">Gilles LAMIRAL</a></strong>
|
||||
</p>
|
||||
|
||||
|
||||
<div class="container-fluid" >
|
||||
<div class="row">
|
||||
<div class="text-center">
|
||||
<a href="https://imapsync.lamiral.info/">
|
||||
<img alt="Imapsync home page" src="https://imapsync.lamiral.info/X/logo_imapsync_Xn.png" height="38" width="60">
|
||||
</a>
|
||||
<a href="#top" title="Top of the page" class="btn btn-info " role="button">Top</a>
|
||||
<!-- <a href="#buttons" class="btn btn-info scripton" role="button">Consoles</a> -->
|
||||
<a href="#bottom" title="Bottom of the page" class="btn btn-info active" role="button">Bottom</a>
|
||||
<br>
|
||||
<small> ($Id: imapsync_form.html,v 1.69 2019/03/31 22:25:15 gilles Exp $) </small><br>
|
||||
Terms and conditions for anything: <a href="https://imapsync.lamiral.info/LICENSE">No limits to do anything with this work and this license!</a><br>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<script
|
||||
src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"
|
||||
integrity="sha384-xBuQ/xzmlsLoJpyjoggmTEz8OWUFM0/RC5BsqQBDX2v5cMvDHcMakNTNrHIW2I5f"
|
||||
crossorigin="anonymous"
|
||||
>
|
||||
</script>
|
||||
|
||||
<script
|
||||
src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"
|
||||
integrity="sha384-Tc5IQib027qvyjSMfHjOMaLkfuWVxZxUPnCJA7l2mCWNIpG9mGCD8wGNIcPD7Txa"
|
||||
crossorigin="anonymous"
|
||||
>
|
||||
</script>
|
||||
|
||||
|
||||
<script
|
||||
src="imapsync_form.js"
|
||||
>
|
||||
</script>
|
||||
|
||||
</body>
|
||||
</html>
|
455
X/imapsync_form_extra.html
Executable file
455
X/imapsync_form_extra.html
Executable file
|
@ -0,0 +1,455 @@
|
|||
<!DOCTYPE html>
|
||||
<!-- $Id: imapsync_form_extra.html,v 1.2 2019/06/25 16:38:24 gilles Exp gilles $ -->
|
||||
|
||||
<html lang="en" id="top">
|
||||
|
||||
<head>
|
||||
<title>Imapsync online</title>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
|
||||
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css"
|
||||
integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">
|
||||
|
||||
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap-theme.min.css"
|
||||
integrity="sha384-rHyoN1iRsVXV4nD0JutlnGaslCJuC7uwjduW9SVrLvRYooPp2bWYgmgJQIXwl/Sp" crossorigin="anonymous">
|
||||
|
||||
<link rel="stylesheet" href="imapsync_form.css">
|
||||
|
||||
<link rel="license" href="https://imapsync.lamiral.info/NOLIMIT">
|
||||
|
||||
|
||||
<noscript>
|
||||
<link rel="stylesheet" href="noscript.css">
|
||||
</noscript>
|
||||
|
||||
</head>
|
||||
|
||||
<body>
|
||||
|
||||
|
||||
<div class="hidden scripton">
|
||||
<pre id="tests">
|
||||
</pre>
|
||||
<input type="checkbox" id="test_checkbox">
|
||||
<input type="text" id="test_text">
|
||||
<input type="radio" id="test_radio" name="test_radio" value="first" >
|
||||
<input type="radio" id="test_radio" name="test_radio" value="second" >
|
||||
</div>
|
||||
|
||||
<div class="container-fluid" >
|
||||
|
||||
<div class="row">
|
||||
<div class="text-center">
|
||||
<a href="https://imapsync.lamiral.info/">
|
||||
<img alt="Imapsync home" title="Imapsync home page" src="https://imapsync.lamiral.info/X/logo_imapsync_Xn.png" height="38" width="60">
|
||||
</a>
|
||||
<a href="#top" title="Top of the page" class="btn btn-info " role="button">Top</a>
|
||||
<!-- <a href="#payment" class="btn btn-success" data-toggle="collapse">Pricing</a> -->
|
||||
<!-- <a href="#buttons" class="btn btn-info scripton" role="button">Consoles</a> -->
|
||||
<a href="#bottom" title="Bottom of the page" class="btn btn-info active" role="button">Bottom</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<h1 class="text-center">Imapsync online</h1>
|
||||
|
||||
<p class="text-center"> <strong>Copy</strong>/synchronize a <strong>complete</strong> mailbox to another, without <strong>duplicates!</strong></p>
|
||||
|
||||
<!-- Paypal part start
|
||||
new: NDGMR6TLFZ926
|
||||
old: H2YTURNFT4XT4
|
||||
-->
|
||||
|
||||
<!-- A button above the pricing form, not very beautiful...
|
||||
I should give it a try anyway because nearly no one buy this service...
|
||||
<div class="text-center">
|
||||
<a href="#payment" class="btn btn-warning btn-lg" data-toggle="collapse">Pricing</a>
|
||||
</div>
|
||||
-->
|
||||
|
||||
<!-- the "in" makes the form not collapsed by default
|
||||
Remove the in in order to mask the pricing section
|
||||
<div id="payment" class="well text-center collapse in" > -->
|
||||
<div id="payment" class="well text-center collapse out" >
|
||||
<p class="lead">Pay by usage type</p>
|
||||
<form action="https://www.paypal.com/cgi-bin/webscr" method="post" target="_blank">
|
||||
<input type="hidden" name="cmd" value="_s-xclick" />
|
||||
<input type="hidden" name="hosted_button_id" value="H2YTURNFT4XT4" />
|
||||
<input type="hidden" name="on0" value="imapsync choice" />
|
||||
<fieldset>
|
||||
<!--
|
||||
<label data-toggle="tooltip" data-placement="top" title="Fair enough"
|
||||
class="radio-inline"><input type="radio" name="os0" value="Tiny" > €1,00 </label>
|
||||
-->
|
||||
<label data-toggle="tooltip" data-placement="top" title="A big mailbox"
|
||||
class="radio-inline"><input type="radio" name="os0" value="Small" > €6,00 </label>
|
||||
<label data-toggle="tooltip" data-placement="top" title="Several mailboxes to migrate"
|
||||
class="radio-inline"><input type="radio" name="os0" value="Normal" checked > €59,00 </label>
|
||||
<!--
|
||||
<label data-toggle="tooltip" data-placement="top" title="Tons of gigabytes to copy"
|
||||
class="radio-inline"><input type="radio" name="os0" value="High" > €125,00 </label>
|
||||
-->
|
||||
<br>
|
||||
<input type="hidden" name="currency_code" value="EUR" />
|
||||
<input type="image" src="https://www.paypalobjects.com/en_US/i/btn/btn_buynowCC_LG.gif" name="submit" alt="PayPal - A safe, easy way to pay online!" />
|
||||
</fieldset>
|
||||
<p>
|
||||
<strong>30-day money back guarantee!</strong> <br>
|
||||
<em>No question nor condition to get a refund, really, just request it and you'll sure get a refund!</em>
|
||||
</p>
|
||||
</form>
|
||||
</div>
|
||||
<!-- Paypal part end -->
|
||||
|
||||
|
||||
<form id="form" action="/cgi-bin/imapsync" method="post" autocomplete="on">
|
||||
<div id="form_row" class="row">
|
||||
<div id="account1" class="col-md-5" >
|
||||
<fieldset>
|
||||
<legend class="text-center h2">IMAP source mailbox</legend>
|
||||
|
||||
<label for="user1">Login</label>
|
||||
<div class="input-group form-group">
|
||||
<span class="input-group-addon"><i class="glyphicon glyphicon-user"> </i></span>
|
||||
<input
|
||||
data-toggle="tooltip" data-placement="bottom" title="It is usually an email address or its left part before @"
|
||||
type="text" class="form-control input-lg" id="user1" name="user1" tabindex="1"
|
||||
placeholder="Enter login name">
|
||||
</div>
|
||||
|
||||
<label for="password1">Password</label>
|
||||
<label class="checkbox-inline out">
|
||||
<input type="checkbox" id="showpassword1"> show password
|
||||
</label>
|
||||
<div class="input-group form-group">
|
||||
<span class="input-group-addon"><i class="glyphicon glyphicon-lock"></i></span>
|
||||
<input
|
||||
data-toggle="tooltip" data-placement="bottom" title="Passwords are not stored on the server"
|
||||
type="password" class="form-control input-lg" id="password1" name="password1" tabindex="2"
|
||||
placeholder="Enter password">
|
||||
</div>
|
||||
|
||||
<label for="host1">Server</label>
|
||||
<div class="input-group form-group">
|
||||
<span class="input-group-addon"><i class="glyphicon glyphicon-cloud"></i></span>
|
||||
<input
|
||||
data-toggle="tooltip" data-placement="bottom" title="IMAP transfers are done with encryption if the servers support it."
|
||||
list="servers1" type="text" class="form-control input-lg" id="host1" name="host1" tabindex="3"
|
||||
placeholder="Enter imap source server name or IP address">
|
||||
<datalist id="servers1">
|
||||
<option value="imap.gmail.com">
|
||||
<option value="outlook.office365.com">
|
||||
<option value="imap.mail.yahoo.com">
|
||||
</datalist>
|
||||
</div>
|
||||
|
||||
<div class="form-group collapse extra_param">
|
||||
<label class="checkbox-inline">
|
||||
<input
|
||||
data-toggle="tooltip" data-placement="bottom" title="Be careful with this option"
|
||||
type="checkbox" id="delete1" name="delete1">Move sync. Deletes messages on source mailbox after a successful transfer.
|
||||
</label>
|
||||
</div>
|
||||
|
||||
<div class="form-group collapse extra_param" >
|
||||
<label for="subfolder1">Sub-folder</label>
|
||||
<div class="input-group form-group">
|
||||
<span class="input-group-addon"><i class="glyphicon glyphicon-folder-open"></i></span>
|
||||
<input
|
||||
data-toggle="tooltip" data-placement="bottom" title="A subfolder where all the source mailbox comes from."
|
||||
type="text" class="form-control input-lg" id="subfolder1" name="subfolder1"
|
||||
placeholder="Enter sub-folder name">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<br>
|
||||
</div>
|
||||
</fieldset>
|
||||
</div>
|
||||
|
||||
<div id="parameters" class="col-md-2" >
|
||||
<div>
|
||||
<br>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<label class="checkbox-inline">
|
||||
<input
|
||||
data-toggle="tooltip" data-placement="bottom" title="Shows what would be done without really doing it."
|
||||
type="checkbox" id="dry" name="dry" >Dry run.
|
||||
</label>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<label class="checkbox-inline">
|
||||
<input
|
||||
data-toggle="tooltip" data-placement="bottom" title="Checks credentials without syncing anything."
|
||||
type="checkbox" id="justlogin" name="justlogin" >Login only.
|
||||
</label>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<label class="checkbox-inline">
|
||||
<input
|
||||
data-toggle="tooltip" data-placement="bottom" title="Shows folders sizes and exits."
|
||||
type="checkbox" id="justfoldersizes" name="justfoldersizes" >Just folders sizes.
|
||||
</label>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<label class="checkbox-inline">
|
||||
<input
|
||||
data-toggle="tooltip" data-placement="bottom" title="Just create the folder hierarchy, messages are not synced."
|
||||
type="checkbox" id="justfolders" name="justfolders" >Folders only.
|
||||
</label>
|
||||
</div>
|
||||
|
||||
|
||||
<div>
|
||||
<br>
|
||||
</div>
|
||||
|
||||
<div id="button_extra_param" class="text-center scripton">
|
||||
<button type="button" class="btn btn-default btn-block" data-toggle="collapse"
|
||||
data-target=".extra_param">Show / Hide extra parameters</button>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<br>
|
||||
</div>
|
||||
|
||||
<div id="button_swap" class="text-center scripton">
|
||||
<button type="button" class="btn btn-default btn-block" id="swap">
|
||||
Swap Source <span class="glyphicon glyphicon-transfer"></span> Destination
|
||||
</button>
|
||||
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<br>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
<div id="account2" class="col-md-5" >
|
||||
<fieldset>
|
||||
<legend class="text-center h2">IMAP destination mailbox</legend>
|
||||
|
||||
<label for="user2">Login</label>
|
||||
<div class="input-group form-group">
|
||||
<span class="input-group-addon"><i class="glyphicon glyphicon-user"></i></span>
|
||||
<input
|
||||
data-toggle="tooltip" data-placement="bottom" title="It is usually an email address or its left part before @"
|
||||
type="text" class="form-control input-lg" id="user2" name="user2" tabindex="6"
|
||||
placeholder="Enter login name">
|
||||
</div>
|
||||
<label for="password2">Password</label>
|
||||
<label class="checkbox-inline out">
|
||||
<input type="checkbox" id="showpassword2"> show password
|
||||
</label>
|
||||
<div class="input-group form-group">
|
||||
<span class="input-group-addon"><i class="glyphicon glyphicon-lock"></i></span>
|
||||
<input
|
||||
data-toggle="tooltip" data-placement="bottom" title="Passwords are not stored on the server"
|
||||
type="password" class="form-control input-lg" id="password2" name="password2" tabindex="7"
|
||||
placeholder="Enter password">
|
||||
</div>
|
||||
|
||||
<label for="host2">Server</label>
|
||||
<div class="input-group form-group">
|
||||
<span class="input-group-addon"><i class="glyphicon glyphicon-cloud"></i></span>
|
||||
<input
|
||||
data-toggle="tooltip" data-placement="bottom" title="IMAP transfers are done with encryption if the servers support it."
|
||||
list="servers2" type="text" class="form-control input-lg" id="host2" name="host2" tabindex="8"
|
||||
placeholder="Enter imap destination server name or IP address">
|
||||
<datalist id="servers2">
|
||||
<option value="imap.gmail.com">
|
||||
<option value="outlook.office365.com">
|
||||
<option value="imap.mail.yahoo.com">
|
||||
</datalist>
|
||||
</div>
|
||||
<!-- -->
|
||||
<div class="form-group collapse extra_param">
|
||||
<label class="checkbox-inline">
|
||||
<input
|
||||
data-toggle="tooltip" data-placement="bottom" title="Be careful with this option"
|
||||
type="checkbox" id="delete2" name="delete2" tabindex="9">Strict sync. Deletes messages on destination mailbox that are not at the source mailbox.
|
||||
</label>
|
||||
</div>
|
||||
|
||||
<div class="form-group collapse extra_param" id="extra_subfolder2" >
|
||||
<label for="subfolder2">Sub-folder</label>
|
||||
<div class="input-group form-group">
|
||||
<span class="input-group-addon"><i class="glyphicon glyphicon-folder-open"></i></span>
|
||||
<input
|
||||
data-toggle="tooltip" data-placement="bottom" title="A subfolder where all the source mailbox will go."
|
||||
type="text" class="form-control input-lg" id="subfolder2" name="subfolder2"
|
||||
placeholder="Enter sub-folder name">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<!-- -->
|
||||
<div>
|
||||
<br>
|
||||
</div>
|
||||
</fieldset>
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
<input type="hidden" name="automap" value="on">
|
||||
<input type="hidden" name="addheader" value="on">
|
||||
<!-- --#>
|
||||
<input type="hidden" name="simulong" value="360">
|
||||
<!-- -->
|
||||
|
||||
|
||||
<a name="buttons"></a>
|
||||
<hr>
|
||||
|
||||
<!-- Classical button to go to the log only -->
|
||||
<noscript>
|
||||
<div class="row">
|
||||
<div class="col-sm-12 padd0" >
|
||||
<button type="submit" class="btn btn-success btn-lg center-block btn-block">Go sync!</button>
|
||||
</div>
|
||||
</div>
|
||||
</noscript>
|
||||
|
||||
<!-- Javascript buttons using xhr -->
|
||||
<div class="row scripton">
|
||||
<div class="col-sm-6 padd0" >
|
||||
<button id="bt-sync" type="button"
|
||||
class="btn btn-success btn-lg center-block btn-block"
|
||||
tabindex="11"
|
||||
data-toggle="tooltip" data-placement="top"
|
||||
title="Launch the sync! You can abort the sync with the red Abort button nearby or by closing the tab/window."
|
||||
>
|
||||
Sync or resync!<br>
|
||||
<span class="glyphicon glyphicon-envelope"></span>
|
||||
<span class="glyphicon glyphicon-arrow-right"></span>
|
||||
<span class="glyphicon glyphicon-envelope"></span>
|
||||
</button>
|
||||
</div>
|
||||
<div class="col-sm-6 padd0" >
|
||||
<button id="bt-abort" type="button"
|
||||
class="btn btn-danger btn-lg center-block btn-block" tabindex="12"
|
||||
data-toggle="tooltip" data-placement="top"
|
||||
title="Abort the sync! You can restart the sync later, no duplicates should happen."
|
||||
>
|
||||
Abort!<br>
|
||||
<span class="glyphicon glyphicon-scissors"></span>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
|
||||
<div class="row scripton" id="consoles" >
|
||||
|
||||
<pre id="progress"></pre>
|
||||
|
||||
<div class="col-sm-6 well">
|
||||
<h2 class="text-center">Console of imapsync launch</h2>
|
||||
<pre id="console">
|
||||
|
||||
|
||||
|
||||
</pre>
|
||||
<a id="link_to_bottom" href="#bottom">Bottom of imapsync log</a>
|
||||
</div>
|
||||
|
||||
<div class="col-sm-6 well">
|
||||
<h2 class="text-center">Console of abort</h2>
|
||||
<pre id="abort">
|
||||
|
||||
|
||||
|
||||
</pre>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<h2 class="text-center scripton">Log of imapsync run</h2>
|
||||
|
||||
<pre id="output" class="scripton">
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
</pre>
|
||||
|
||||
<a name="bottom"></a>
|
||||
<hr>
|
||||
<p class="text-center">
|
||||
Local bandwidth statistics <br>
|
||||
<a href="/vnstat/vnstati.html">
|
||||
<img alt="Local bandwidth statistics" src="/vnstat/vnstat_vs.png" >
|
||||
</a>
|
||||
</p>
|
||||
|
||||
<p class="text-center">Feel free to contact
|
||||
<strong><a href="https://imapsync.lamiral.info/#AUTHOR" target="_blank">Gilles LAMIRAL</a></strong>
|
||||
</p>
|
||||
|
||||
|
||||
<div class="container-fluid" >
|
||||
<div class="row">
|
||||
<div class="text-center">
|
||||
<a href="https://imapsync.lamiral.info/">
|
||||
<img alt="Imapsync home page" src="https://imapsync.lamiral.info/X/logo_imapsync_Xn.png" height="38" width="60">
|
||||
</a>
|
||||
<a href="#top" title="Top of the page" class="btn btn-info " role="button">Top</a>
|
||||
<!-- <a href="#buttons" class="btn btn-info scripton" role="button">Consoles</a> -->
|
||||
<a href="#bottom" title="Bottom of the page" class="btn btn-info active" role="button">Bottom</a>
|
||||
<br>
|
||||
<small> ($Id: imapsync_form_extra.html,v 1.2 2019/06/25 16:38:24 gilles Exp gilles $) </small><br>
|
||||
Terms and conditions for anything: <a href="https://imapsync.lamiral.info/LICENSE">No limits to do anything with this work and this license!</a><br>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<script
|
||||
src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"
|
||||
integrity="sha384-xBuQ/xzmlsLoJpyjoggmTEz8OWUFM0/RC5BsqQBDX2v5cMvDHcMakNTNrHIW2I5f"
|
||||
crossorigin="anonymous"
|
||||
>
|
||||
</script>
|
||||
|
||||
<script
|
||||
src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"
|
||||
integrity="sha384-Tc5IQib027qvyjSMfHjOMaLkfuWVxZxUPnCJA7l2mCWNIpG9mGCD8wGNIcPD7Txa"
|
||||
crossorigin="anonymous"
|
||||
>
|
||||
</script>
|
||||
|
||||
|
||||
<script
|
||||
src="imapsync_form_new.js"
|
||||
>
|
||||
</script>
|
||||
|
||||
</body>
|
||||
</html>
|
453
X/imapsync_form_new.js
Executable file
453
X/imapsync_form_new.js
Executable file
|
@ -0,0 +1,453 @@
|
|||
|
||||
// $Id: imapsync_form_new.js,v 1.4 2019/06/25 16:34:19 gilles Exp gilles $
|
||||
|
||||
/*jslint browser: true*/ /*global $*/
|
||||
|
||||
|
||||
$(document).ready(
|
||||
function ()
|
||||
{
|
||||
"use strict";
|
||||
// Bootstrap popover and tooltip
|
||||
$("[data-toggle='tooltip']").tooltip();
|
||||
|
||||
var readyStateStr = {
|
||||
"0": "Request not initialized",
|
||||
"1": "Server connection established",
|
||||
"2": "Response headers received",
|
||||
"3": "Processing request",
|
||||
"4": "Finished and response is ready"
|
||||
};
|
||||
|
||||
function is( expected, given, comment )
|
||||
{
|
||||
var message = ": ["
|
||||
+ expected
|
||||
+ "] === ["
|
||||
+ given
|
||||
+ "] "
|
||||
+ comment
|
||||
+ "\n" ;
|
||||
if ( expected === given )
|
||||
{
|
||||
message = "ok " + message ;
|
||||
}
|
||||
else
|
||||
{
|
||||
message = "Nok" + message ;
|
||||
}
|
||||
$("#tests").append( message ) ;
|
||||
}
|
||||
|
||||
function last_eta( string )
|
||||
{
|
||||
// return the last occurrence of the substring "ETA: ...\n"
|
||||
// or ""
|
||||
var eta ;
|
||||
var last_found ;
|
||||
|
||||
if ( undefined === string )
|
||||
{
|
||||
return "" ;
|
||||
}
|
||||
|
||||
var eta_re = /ETA:.*\n/g ;
|
||||
|
||||
eta = string.match( eta_re ) ;
|
||||
if ( eta )
|
||||
{
|
||||
last_found = eta[eta.length -1 ] ;
|
||||
return last_found ;
|
||||
}
|
||||
else
|
||||
{
|
||||
return "" ;
|
||||
}
|
||||
}
|
||||
|
||||
function tests_last_eta()
|
||||
{
|
||||
is( "", last_eta( ), "last_eta: no args => empty string" ) ;
|
||||
is( "", last_eta( "" ), "last_eta: empty => empty string" ) ;
|
||||
is( "", last_eta( "ETA" ), "last_eta: ETA => empty string" ) ;
|
||||
is( "", last_eta( "ETA: but no CR" ),
|
||||
"last_eta: ETA: but no CR => empty string" ) ;
|
||||
|
||||
is(
|
||||
"ETA: with CR\n",
|
||||
last_eta( "Blabla ETA: with CR\n" ),
|
||||
"last_eta: ETA: with CR => ETA: with CR"
|
||||
) ;
|
||||
|
||||
is(
|
||||
"ETA: 2 with CR\n",
|
||||
last_eta( "Blabla ETA: 1 with CR\nBlabla ETA: 2 with CR\n" ),
|
||||
"last_eta: several ETA: with CR => ETA: 2 with CR"
|
||||
) ;
|
||||
}
|
||||
|
||||
function refreshLog(xhr)
|
||||
{
|
||||
var slice_length ;
|
||||
$("#output").text(xhr.responseText) ;
|
||||
if (xhr.readyState === 4) {
|
||||
slice_length = -2400 ;
|
||||
}
|
||||
else
|
||||
{
|
||||
slice_length = -240 ;
|
||||
}
|
||||
$("#progress").text( last_eta( xhr.responseText.slice( slice_length ) ) ) ;
|
||||
}
|
||||
|
||||
|
||||
|
||||
function handleRun(xhr, timerRefreshLog)
|
||||
{
|
||||
|
||||
$("#console").text("Status: " + xhr.status + " " + xhr.statusText + "\n" + "State: " + readyStateStr[xhr.readyState] + "\n") ;
|
||||
|
||||
if (xhr.readyState === 4) {
|
||||
// var headers = xhr.getAllResponseHeaders();
|
||||
// $("#console").append(headers);
|
||||
// $("#console").append("See the completed log\n");
|
||||
$("#link_to_bottom").show();
|
||||
clearInterval(timerRefreshLog);
|
||||
refreshLog(xhr); // a last time
|
||||
$("#bt-sync").prop("disabled", false); // back to enable state for next run
|
||||
}
|
||||
}
|
||||
|
||||
function imapsync()
|
||||
{
|
||||
var querystring = $("#form").serialize();
|
||||
$("#abort").text("\n\n"); // clean abort console
|
||||
$("#output").text("Here comes the log!\n\n");
|
||||
|
||||
if ( "imap.gmail.com" === $("#host1").val() )
|
||||
{
|
||||
querystring = querystring + "&gmail1=on";
|
||||
}
|
||||
if ( "imap.gmail.com" === $("#host2").val() )
|
||||
{
|
||||
querystring = querystring + "&gmail2=on";
|
||||
}
|
||||
|
||||
var xhr;
|
||||
xhr = new XMLHttpRequest();
|
||||
var timerRefreshLog = setInterval(
|
||||
function ()
|
||||
{
|
||||
refreshLog(xhr);
|
||||
}, 5000 ) ;
|
||||
xhr.onreadystatechange = function ()
|
||||
{
|
||||
handleRun(xhr, timerRefreshLog);
|
||||
};
|
||||
xhr.open("POST", "/cgi-bin/imapsync", true);
|
||||
xhr.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
|
||||
xhr.send(querystring);
|
||||
}
|
||||
|
||||
|
||||
function handleAbort(xhr)
|
||||
{
|
||||
|
||||
$("#abort").text("Status: " + xhr.status + " " + xhr.statusText + "\n" + "State: " + readyStateStr[xhr.readyState] + "\n\n");
|
||||
|
||||
if (xhr.readyState === 4)
|
||||
{
|
||||
$("#abort").append(xhr.responseText);
|
||||
$("#bt-sync").prop("disabled", false);
|
||||
$("#bt-abort").prop("disabled", false); // back for next abort
|
||||
}
|
||||
}
|
||||
|
||||
function abort()
|
||||
{
|
||||
var querystring = $("#form").serialize() + "&abort=on";
|
||||
var xhr;
|
||||
xhr = new XMLHttpRequest();
|
||||
xhr.onreadystatechange = function ()
|
||||
{
|
||||
handleAbort(xhr);
|
||||
};
|
||||
xhr.open("POST", "/cgi-bin/imapsync", true);
|
||||
xhr.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
|
||||
xhr.send(querystring);
|
||||
}
|
||||
|
||||
function store( id )
|
||||
{
|
||||
var stored ;
|
||||
$( "#tests" ).append( "Eco: " + id + " type is " + $( id ).attr( "type" ) + "\n" ) ;
|
||||
if ( "text" === $( id ).attr( "type" ) || "password" === $( id ).attr( "type" ) )
|
||||
{
|
||||
localStorage.setItem( id, $(id).val() ) ;
|
||||
stored = $(id).val() ;
|
||||
}
|
||||
else if ( "checkbox" === $( id ).attr( "type" ) )
|
||||
{
|
||||
$( "#tests" ).append( "Eco: " + id + " checked is " + $( id )[0].checked + "\n" ) ;
|
||||
localStorage.setItem( id, $( id )[0].checked ) ;
|
||||
stored = $( id )[0].checked ;
|
||||
}
|
||||
return stored ;
|
||||
}
|
||||
|
||||
function retrieve( id )
|
||||
{
|
||||
var retrieved ;
|
||||
$( "#tests" ).append( "Eco: " + id + " type is " + $( id ).attr( "type" ) + " length is " + $( id ).length + "\n" ) ;
|
||||
if ( "text" === $( id ).attr( "type" ) || "password" === $( id ).attr( "type" ) )
|
||||
{
|
||||
$( id ).val( localStorage.getItem( id ) ) ;
|
||||
retrieved = $( id ).val() ;
|
||||
}
|
||||
else if ( "checkbox" === $( id ).attr( "type" ) )
|
||||
{
|
||||
$( "#tests" ).append( "Eco: " + id + " getItem is " + localStorage.getItem( id ) + "\n" ) ;
|
||||
$( id )[0].checked = JSON.parse( localStorage.getItem( id ) ) ;
|
||||
retrieved = $( id )[0].checked ;
|
||||
}
|
||||
return retrieved ;
|
||||
}
|
||||
|
||||
function tests_store_retrieve()
|
||||
{
|
||||
if ( $("#tests").length !== 0 )
|
||||
{
|
||||
is( 1, 1, "one equals one" ) ;
|
||||
// isnot( 0, 1, "zero differs one" ) ;
|
||||
|
||||
// no exist
|
||||
is( undefined, store( "#test_noexists" ), "store: #test_noexists" ) ;
|
||||
is( undefined, retrieve( "#test_noexists" ), "retrieve: #test_noexists" ) ;
|
||||
is( undefined, retrieve( "#test_noexists2" ), "retrieve: #test_noexists2" ) ;
|
||||
|
||||
// input text
|
||||
$("#test_text" ).val( "foo" ) ;
|
||||
is( "foo", $("#test_text" ).val( ), "#test_text val = foo" ) ;
|
||||
is( "foo", store( "#test_text" ), "store: #test_text" ) ;
|
||||
$("#test_text" ).val( "bar" ) ;
|
||||
is( "bar", $("#test_text" ).val( ), "#test_text val = bar" ) ;
|
||||
is( "foo", retrieve( "#test_text" ), "retrieve: #test_text = foo" ) ;
|
||||
is( "foo", $("#test_text" ).val( ), "#test_text val = foo" ) ;
|
||||
|
||||
|
||||
// input check button
|
||||
$( "#test_checkbox" ).prop( "checked", true );
|
||||
is( true, store( "#test_checkbox" ), "store: #test_checkbox checked" ) ;
|
||||
|
||||
$( "#test_checkbox" ).prop( "checked", false );
|
||||
is( true, retrieve( "#test_checkbox" ), "retrieve: #test_checkbox = true" ) ;
|
||||
|
||||
$( "#test_checkbox" ).prop( "checked", false );
|
||||
is( false, store( "#test_checkbox" ), "store: #test_checkbox not checked" ) ;
|
||||
$( "#test_checkbox" ).prop( "checked", true );
|
||||
is( false, retrieve( "#test_checkbox" ), "retrieve: #test_checkbox = false" ) ;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
function store_form()
|
||||
{
|
||||
if ( Storage !== "undefined")
|
||||
{
|
||||
// Code for localStorage.
|
||||
store("#user1") ;
|
||||
store("#password1") ;
|
||||
store("#host1") ;
|
||||
store("#subfolder1") ;
|
||||
store("#showpassword1") ;
|
||||
|
||||
store("#user2") ;
|
||||
store("#password2") ;
|
||||
store("#host2") ;
|
||||
store("#subfolder2") ;
|
||||
store("#showpassword2") ;
|
||||
|
||||
store("#dry") ;
|
||||
store("#justlogin") ;
|
||||
store("#justfolders") ;
|
||||
store("#justfoldersizes") ;
|
||||
|
||||
localStorage.account1_background_color = $("#account1").css("background-color") ;
|
||||
localStorage.account2_background_color = $("#account2").css("background-color") ;
|
||||
}
|
||||
}
|
||||
|
||||
function show_extra_if_needed()
|
||||
{
|
||||
if ( $("#subfolder1").length && $("#subfolder1").val().length > 0 )
|
||||
{
|
||||
$(".extra_param").show() ;
|
||||
}
|
||||
if ( $("#subfolder2").length && $("#subfolder2").val().length > 0 )
|
||||
{
|
||||
$(".extra_param").show() ;
|
||||
}
|
||||
}
|
||||
|
||||
function retrieve_form()
|
||||
{
|
||||
if ( Storage !== "undefined" )
|
||||
{
|
||||
// Code for localStorage.
|
||||
retrieve( "#user1" ) ;
|
||||
retrieve( "#password1" ) ;
|
||||
// retrieve("#showpassword1") ;
|
||||
retrieve( "#host1" ) ;
|
||||
retrieve( "#subfolder1" ) ;
|
||||
|
||||
retrieve( "#user2" ) ;
|
||||
retrieve( "#password2" ) ;
|
||||
// retrieve("#showpassword2") ;
|
||||
retrieve( "#host2" ) ;
|
||||
retrieve( "#subfolder2" ) ;
|
||||
|
||||
retrieve( "#dry" ) ;
|
||||
retrieve( "#justlogin" ) ;
|
||||
retrieve( "#justfolders" ) ;
|
||||
retrieve( "#justfoldersizes" ) ;
|
||||
|
||||
// In case
|
||||
// localStorage.removeItem( "account1_background_color" ) ;
|
||||
// localStorage.removeItem( "account2_background_color" ) ;
|
||||
|
||||
if ( localStorage.account1_background_color )
|
||||
{
|
||||
$("#account1").css("background-color", localStorage.account1_background_color ) ;
|
||||
}
|
||||
if ( localStorage.account2_background_color )
|
||||
{
|
||||
$("#account2").css("background-color", localStorage.account2_background_color ) ;
|
||||
}
|
||||
|
||||
// Show the extra parameters if they are not empty because it would be dangerous
|
||||
// to retrieve them without knowing
|
||||
show_extra_if_needed() ;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
function showpassword( id, button )
|
||||
{
|
||||
var x = document.getElementById( id );
|
||||
if ( button.checked )
|
||||
{
|
||||
x.type = "text";
|
||||
} else {
|
||||
x.type = "password";
|
||||
}
|
||||
}
|
||||
|
||||
function init()
|
||||
{
|
||||
// in case of a manual refresh, start with
|
||||
$("#bt-sync").prop("disabled", false);
|
||||
$("#bt-abort").prop("disabled", false);
|
||||
$("#link_to_bottom").hide();
|
||||
retrieve_form();
|
||||
|
||||
$("#showpassword1").click(
|
||||
function ()
|
||||
{
|
||||
// does not change jslint report...
|
||||
/*jshint validthis: true */
|
||||
var button = this ;
|
||||
showpassword( "password1", button ) ;
|
||||
}
|
||||
);
|
||||
|
||||
|
||||
$("#showpassword2").click(
|
||||
function ()
|
||||
{
|
||||
var button = this ;
|
||||
showpassword( "password2", button ) ;
|
||||
}
|
||||
);
|
||||
|
||||
|
||||
$("#bt-sync").click(
|
||||
function ()
|
||||
{
|
||||
$("#bt-sync").prop("disabled", true);
|
||||
$("#bt-abort").prop("disabled", false);
|
||||
$("#link_to_bottom").hide();
|
||||
store_form();
|
||||
imapsync();
|
||||
}
|
||||
);
|
||||
|
||||
$("#bt-abort").click(
|
||||
function ()
|
||||
{
|
||||
$("#bt-sync").prop("disabled", true);
|
||||
$("#bt-abort").prop("disabled", true);
|
||||
abort();
|
||||
}
|
||||
);
|
||||
|
||||
|
||||
$.fn.swapWith = function(to)
|
||||
{
|
||||
var temp = $(to).val();
|
||||
$(to).val($(this).val());
|
||||
$(this).val(temp);
|
||||
};
|
||||
|
||||
|
||||
$("#swap").click(
|
||||
function()
|
||||
{
|
||||
// swaping colors can't use swapWith()
|
||||
var temp1 = $("#account1").css("background-color") ;
|
||||
var temp2 = $("#account2").css("background-color") ;
|
||||
$("#account1").css("background-color", temp2 );
|
||||
$("#account2").css("background-color", temp1 );
|
||||
|
||||
$("#user1").swapWith("#user2");
|
||||
$("#password1").swapWith("#password2");
|
||||
$("#host1").swapWith("#host2");
|
||||
$("#subfolder1").swapWith("#subfolder2");
|
||||
|
||||
var temp = $("#showpassword1")[0].checked ;
|
||||
$("#showpassword1")[0].checked = $("#showpassword2")[0].checked ;
|
||||
$("#showpassword2")[0].checked = temp ;
|
||||
showpassword( "password1", $("#showpassword1")[0] ) ;
|
||||
showpassword( "password2", $("#showpassword2")[0] ) ;
|
||||
}
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
function progress_bar_update( string )
|
||||
{
|
||||
//
|
||||
return ;
|
||||
}
|
||||
|
||||
|
||||
|
||||
function tests()
|
||||
{
|
||||
if ( $("#tests").length !== 0 )
|
||||
{
|
||||
tests_store_retrieve() ;
|
||||
tests_last_eta() ;
|
||||
}
|
||||
}
|
||||
|
||||
init( ) ;
|
||||
tests( ) ;
|
||||
|
||||
}
|
||||
|
||||
);
|
||||
|
13
X/noscript.css
Executable file
13
X/noscript.css
Executable file
|
@ -0,0 +1,13 @@
|
|||
|
||||
|
||||
.scripton {
|
||||
display:none;
|
||||
}
|
||||
|
||||
.collapse {
|
||||
display: block;
|
||||
}
|
||||
|
||||
.out {
|
||||
display:none;
|
||||
}
|
|
@ -12,6 +12,16 @@
|
|||
|
||||
<h1>Imapsync online</h1>
|
||||
|
||||
|
||||
<input
|
||||
data-toggle="tooltip" data-placement="top" title="It is usually an email address or its left part before @"
|
||||
type="text" class="form-control input-lg" id="user1" name="user1" tabindex="1"
|
||||
placeholder="Enter source login name">
|
||||
|
||||
<pre id="user2">
|
||||
</pre>
|
||||
|
||||
|
||||
<button type="button"
|
||||
onclick="imapsync('?lalala=zzz&host1=sss&user1=uuu&password1=uuu&host2=ttt&user2=uuu&password2=uuu&simulong=22&debugenv=on', handleRun)"
|
||||
>Run imapsync
|
||||
|
@ -45,6 +55,9 @@
|
|||
|
||||
<script>
|
||||
|
||||
$("#user2").text("toto");
|
||||
$("#user1").val("RRRR");
|
||||
|
||||
var readyStateStr = {
|
||||
0: "Request not initialized",
|
||||
1: "Server connection established",
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
^Here is imapsync
|
||||
^Load end is
|
||||
^Load is
|
||||
^Server is on heavy load
|
||||
^Temp directory is
|
||||
^Current directory is
|
||||
^REMOTE_ADDR
|
||||
|
@ -37,5 +38,6 @@
|
|||
^Exiting with return value
|
||||
^Memory consumption
|
||||
^Memory consumption at the end
|
||||
failure: Error login
|
||||
^Read:.*\* *ID
|
||||
failure: Error login
|
||||
failure: can not open imap connection on
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue