1
0
mirror of https://github.com/imapsync/imapsync.git synced 2024-11-16 15:52:47 +01:00
This commit is contained in:
Nick Bebout 2011-06-14 05:59:46 -05:00
parent 09dfa9982d
commit 8f6e3e2a2d
50 changed files with 576 additions and 12563 deletions

View File

@ -1,26 +0,0 @@
===== Synopsis =====
$mailbox_1 = Mail::imapsync::mailbox->new();
$mailbox_2 = Mail::imapsync::mailbox->new();
$mailbox_1->host('imap1.lala.org');
$mailbox_1->user('toto1');
...
$mailbox_2->host('imap2.lala.org');
$mailbox_2->user('toto2');
...
$transfer = Mail::imapsync::transfer->new();
$transfer->sync($mailbox_1, $mailbox_2);
- an object for mailbox
- an object for a transfer
- ?an object for a folder?
- ?an object for a message?

View File

@ -1,5 +1,5 @@
#!/bin/cat
# $Id: CREDITS,v 1.156 2011/03/15 00:51:57 gilles Exp gilles $
# $Id: CREDITS,v 1.157 2011/05/07 02:30:05 gilles Exp gilles $
If you want to make a donation to the author, Gilles LAMIRAL,
use any of the following ways:
@ -30,6 +30,10 @@ I thank very much all of these people.
I thank also very much all people who bought imapsync from the homepage
but I don't cite them here.
Unknow
Contributed by giving the book
20.31 "Fluid Concepts And Creative Analogies: Computer Models Of The Fundamental Mechanisms Of Thought"
Khalid Shakir
Contributed by giving the book
75.00 "Selected Papers on Fun and Games [Hardcover]"
@ -996,6 +1000,8 @@ Eric Yung
Total amount of book prices :
c \
20.31+\
\
75.00+\
\
35.16+\

View File

@ -1,17 +1,71 @@
RCS file: RCS/imapsync,v
Working file: imapsync
head: 1.411
head: 1.422
branch:
locks: strict
gilles: 1.411
gilles: 1.422
access list:
symbolic names:
keyword substitution: kv
total revisions: 411; selected revisions: 411
total revisions: 422; selected revisions: 422
description:
----------------------------
revision 1.411 locked by: gilles;
revision 1.422 locked by: gilles;
date: 2011/05/08 17:21:38; author: gilles; state: Exp; lines: +17 -12
Added --debugLIST to track messages list uid or number only.
Bugfix: a lack of variable initialisation caused to fetch no existing messages.
The APPEND error then the FETCH 0 byte error may be fixed now.
----------------------------
revision 1.421
date: 2011/05/08 12:28:10; author: gilles; state: Exp; lines: +8 -8
relogin1 before each folder select.
----------------------------
revision 1.420
date: 2011/05/08 00:54:05; author: gilles; state: Exp; lines: +15 -18
--splitX are set into sub login_imap() now.
----------------------------
revision 1.419
date: 2011/05/08 00:36:36; author: gilles; state: Exp; lines: +58 -8
Added --relogin1 option (--relogin1 5) to force a reconnection when FETCH message fails on host1.
----------------------------
revision 1.418
date: 2011/05/07 22:15:36; author: gilles; state: Exp; lines: +95 -38
Added --debugcontent to avoid debugging content (can be big) with --debug option.
Added --debugflags to permit flag debugging only.
Added --flagsCase to correct flag case that are not RFC compliant \SEEN -> \Seen (on by default).
Added output to track 0 byte messages during the fetch on host1.
----------------------------
revision 1.417
date: 2011/05/05 16:12:02; author: gilles; state: Exp; lines: +7 -7
Bugfix. --proxyauth2 was setting proxyauth1!
Thanks to Denis BREAN!
----------------------------
revision 1.416
date: 2011/05/01 20:44:40; author: gilles; state: Exp; lines: +8 -8
MDaemon 12
Exchange 6.5 host1
----------------------------
revision 1.415
date: 2011/04/30 15:33:31; author: gilles; state: Exp; lines: +20 -14
Bugfix. Modified create_folder() to avoid Inbox -> INBOX problem ("already exists").
----------------------------
revision 1.414
date: 2011/04/30 00:25:38; author: gilles; state: Exp; lines: +41 -19
Bugfix. --maxsize --minsize now work with --useuid
Bugfix. flag sync of already transfered messages now take care of --maxsize --minsize options.
----------------------------
revision 1.413
date: 2011/04/28 22:55:48; author: gilles; state: Exp; lines: +25 -12
--delete2 implies --expunge2 now unless --noexpunge2 is given.
exit if --delete and --delete2 are given together.
Same behavior for --expunge or --expunge1.
----------------------------
revision 1.412
date: 2011/04/28 14:49:59; author: gilles; state: Exp; lines: +17 -15
Added 0 length message tracking when fetching host1.
----------------------------
revision 1.411
date: 2011/04/19 23:34:30; author: gilles; state: Exp; lines: +19 -11
Bugfix for "Folders in host2 not in host1" list when folders are given by --folder option or equivalent.
The old list listed too many folders with --folder INBOX for example.

63
INSTALL
View File

@ -1,4 +1,4 @@
# $Id: INSTALL,v 1.19 2010/11/09 02:52:18 gilles Exp gilles $
# $Id: INSTALL,v 1.20 2011/05/07 02:14:58 gilles Exp gilles $
#
# INSTALL file for imapsync
# imapsync : IMAP sync or copy tool.
@ -7,15 +7,15 @@ INTRODUCTION
------------
imapsync works fine under any Unix OS with perl.
imapsync works fine under Windows (2000, XP) and ActiveState's 5.8 Perl
imapsync.exe works fine under Windows XP, Vista, Seven, 20XX.
imapsync is already available directly on the following distributions (at least):
FreeBSD, Debian, Ubuntu, Gentoo, NetBSD, Darwin, Mandriva and OpenBSD (yeah!).
Get imapsync at
http://www.linux-france.org/prj/imapsync/dist/
UNIX
----
You'll find a compressed tarball called imapsync-x.xx.tgz
Buy imapsync at
http://www.linux-france.org/prj/imapsync/
You'll have access to a compressed tarball called imapsync-x.xx.tgz
where x.xx is the version number. Untar the tarball where
you want (on Unix):
@ -24,14 +24,30 @@ INTRODUCTION
Go into the directory imapsync-x.xx and read the INSTALL file.
You're already reading the INSTALL file.
GETTING
WINDOWS
-------
http://www.linux-france.org/prj/imapsync/dist/
PREREQUISITES
a) Simplest way:
- Buy imapsync.exe at http://www.linux-france.org/prj/imapsync/
- Use imapsync.exe.
b) Hard way:
- Get imapsync-x.xx.tgz
- Install Perl if it isn't already installed.
Strawberry Perl is a good candidate
- Use PPM to install modules listed in the PREREQUISITES section.
PPM is Perl Package Manager.
PREREQUISITES
-------------
This section doesn't concern Windows imapsync.exe users.
You need :
- Perl
try : perl -v
@ -101,34 +117,21 @@ Everything in one command:
perl -mMail::IMAPClient -mDigest::MD5 -mTerm::ReadKey -mIO::Socket::SSL \
-mFile::Spec -mDigest::HMAC_MD5 -mAuthen::NTLM -e ''
INSTALLING
----------
INSTALLING on Unix
------------------
To see what will be done, just run:
make -n install
make -n install
To install imapsync, just run:
make install
make install
or copy the file imapsync where you want it to be.
WINDOWS
-------
a) Simplest way:
- Use imapsync.exe
b) Hard way:
- Install Perl if it isn't already installed.
Strawberry Perl is a good candidate
- Use PPM to install modules listed in the PREREQUISITES section.
PPM is Perl Package Manager.
TESTING
-------
TESTING on Unix
---------------
The test will break as they are home specific.
You need a running imap server on localhost with several accounts

View File

@ -1,5 +1,5 @@
# $Id: Makefile,v 1.67 2011/04/20 01:20:06 gilles Exp gilles $
# $Id: Makefile,v 1.72 2011/05/09 00:11:00 gilles Exp gilles $
.PHONY: help usage all
@ -93,7 +93,10 @@ test_quick_3xx: imapsync tests.sh
CMD_PERL='perl -I./Mail-IMAPClient-3.28/lib' /usr/bin/time sh tests.sh locallocal 1>/dev/null
testv:
nice -40 sh -x tests.sh
sh -x tests.sh
testv3:
CMD_PERL='perl -I./Mail-IMAPClient-3.28/lib' sh -x tests.sh
test: .test_229 .test_3xx
@ -193,8 +196,8 @@ tarball: cidone all imapsync.exe
echo making tarball $(DIST_FILE)
mkdir -p dist
mkdir -p ../prepa_dist/$(DIST_NAME)
rsync -aCv --delete --omit-dir-times --exclude dist/ ./ ../prepa_dist/$(DIST_NAME)/
rsync -av ./imapsync.exe ../prepa_dist/$(DIST_NAME)/
rsync -aCv --delete --omit-dir-times --exclude dist/ --exclude imapsync.exe ./ ../prepa_dist/$(DIST_NAME)/
#rsync -av ./imapsync.exe ../prepa_dist/$(DIST_NAME)/
cd ../prepa_dist && (tar czfv $(DIST_FILE) $(DIST_NAME) || tar czfv $(DIST_FILE) $(DIST_NAME))
#ln -f ../prepa_dist/$(DIST_FILE) dist/
cd ../prepa_dist && md5sum $(DIST_FILE) > $(DIST_FILE).md5.txt
@ -202,7 +205,7 @@ tarball: cidone all imapsync.exe
ls -l ../prepa_dist/$(DIST_FILE)
ks:
rsync -avz . imapsync@ks.lamiral.info:public_html/imapsync
rsync -avz --delete . imapsync@ks.lamiral.info:public_html/imapsync
{ cd /g/var/paypal_reply/ &&\
rsync -av url_exe url_release url_source imapsync@ks.lamiral.info:/g/var/paypal_reply/ \
; }

10
README
View File

@ -3,7 +3,7 @@ NAME
Synchronise mailboxes between two imap servers. Good at IMAP migration.
More than 36 different IMAP server softwares supported with success.
$Revision: 1.411 $
$Revision: 1.422 $
SYNOPSIS
To synchronise imap account "foo" on "imap.truc.org" to imap account
@ -77,7 +77,7 @@ USAGE
[--minage <int>]
[--skipheader <regex>]
[--useheader <string>] [--useheader <string>]
[--nouid1] [--nouid1]
[--nouid1] [--nouid2]
[--usecache]
[--skipsize] [--allowsizemismatch]
[--delete] [--delete2]
@ -332,10 +332,10 @@ IMAP SERVERS
- iPlanet Messaging server 4.15, 5.1, 5.2
- IMail 7.15 (Ipswitch/Win2003), 8.12, 11.03 [host1]
- MailEnable 4.23 [host1] [host2]
- MDaemon 7.0.1, 8.0.2, 8.1, 9.5.4 (Windows server 2003 R2 platform)
- MDaemon 7.0.1, 8.0.2, 8.1, 9.5.4 (Windows server 2003 R2 platform), 12 [host2]
- Mercury 4.1 (Windows server 2000 platform)
- Microsoft Exchange Server 5.5, 6.0.6249.0[host1], 6.0.6487.0[host1],
6.5.7638.1 [host2], Exchange 2007 SP1 (with Update Rollup 2),
6.5.7638.1 [host2], 6.5 [host1], Exchange 2007 SP1 (with Update Rollup 2),
Exchange2007-EP-SP2,
Exchange 2010 RTM (Release to Manufacturing) [host2]
- Mirapoint
@ -422,5 +422,5 @@ SIMILAR SOFTWARES
Feedback (good or bad) will often be welcome.
$Id: imapsync,v 1.411 2011/04/19 23:34:30 gilles Exp gilles $
$Id: imapsync,v 1.422 2011/05/08 17:21:38 gilles Exp gilles $

46
RECORD
View File

@ -1,46 +0,0 @@
+------------------+
| imapsync records |
+------------------+
You can add your own record if you want.
Here is a template.
-------------------------------------------------------------------------------
Your Name/Compagny :
Time to migrate :
Number of mailboxes :
Total size :
Comment :
-------------------------------------------------------------------------------
Your Name/Compagny : Thomas Hallock/Medicus Insurance Company
Time to migrate : The initial sync took about 15 hours. We mirrored the
"from" and "to" mailboxes via cron for a couple of weeks during the
transition. Each day after the initial sync, the script would run for
about 3 hours to catch up with the day-to-day changes. Our mail
server is a Dual-Core Intel Xeon XServe.
Number of mailboxes : 25
Total size : 40+ GB
Comment : It worked flawlessly,
and was even able to address issues I wouldn't have expected it
could, such as synchronizing deletions, and handling differing IMAP
path prefixes between the to and from servers.
-------------------------------------------------------------------------------
Your Name/Compagny : Olivier Morel
Time to migrate : 18 hours
Number of mailboxes : 2200
Total size : 18 Go
Comment : Nous avons terminé notre migration et récupéré l'ensemble
des boites aux lettres grace à votre outil, tout s'est
déroulé à merveille.
-------------------------------------------------------------------------------
Your Name/Compagny : anonymous
Time to migrate : ?
Number of mailboxes : ~10000 mailboxes
Total size : ~70Gb of data
Comment : from Rockliffe Mailsite 4.5 to Courier 4.1.1.20060828-5.

4
TIME
View File

@ -1,3 +1,7 @@
300 Release 1.417. Some numbers section. INSTALL file.
60 Bugfix. --maxsize --minsize now work with --useuid + flag sync of already transfered messages now take care of --maxsize --minsize options.
120 Exit on --delete --delete2. --expunge1 same as --expunge. --delete2 implies --expunge2.
120 Handle the APPEND with {0} byte error just after fetching the message on host1.
40 Groupwize and authuser. Does not work.
540 Invoices build.
35 Bug bug_zero_byte() tests.sh No bug found here. email.

13
TODO
View File

@ -1,5 +1,5 @@
#!/bin/cat
# $Id: TODO,v 1.95 2011/04/16 20:16:47 gilles Exp gilles $
# $Id: TODO,v 1.96 2011/04/26 10:48:03 gilles Exp gilles $
TODO file for imapsync
----------------------
@ -15,8 +15,6 @@ Add a best practice migration tips document.
Write a Mail::imapsync package and use it.
write a comment to http://blog.migrationwiz.com/2010/12/09/imapsync-vs-migrationwiz/
Fix the mailing-list archive bug with From at
the beginning of a line
http://www.linux-france.org/prj/imapsync_list/msg00307.html
@ -25,7 +23,10 @@ Evaluate
http://www.rackspace.com/apps/email_hosting/migrations
http://www.yippiemove.com/
Make --delete2 works with --useuid
Fix Exchange 2010 SP1 issue with --foldersizes when
host2 folders don't exist. $imap->exists calls STATUS.
Is it RFC compliant or an Exchange bug?
Exchange quit after 10 errors.
Fix "\Forwarded" flag bug in courier.
Does \lalala can be forbidden (courier does a
@ -158,6 +159,10 @@ http://asg.web.cmu.edu/cyrus/download/imapd/altnamespace.html
===========================================================================
DONE. Make --delete2 works with --useuid
DONE. write a comment to http://blog.migrationwiz.com/2010/12/09/imapsync-vs-migrationwiz/
DONE. Read http://bugs.gentoo.org/show_bug.cgi?id=354831
Nice conversation.

View File

@ -1 +1 @@
1.411
1.422

View File

@ -1 +1 @@
1.411
1.422

View File

@ -1,6 +0,0 @@
IMAP migration tool
Buy imapsync.exe + source for 30 €
30 days money-back guarantee
linux-france.org/prj/imapsync/
www.linux-france.org/prj/imapsync/

View File

@ -1,10 +0,0 @@
http://freshmeat.net/projects/imapsync/
imapsync is a tool for facilitating incremental recursive IMAP
transfers from one mailbox to another. It is useful for mailbox
migration, and reduces the amount of data transferred by only copying
messages that are not present on both servers. Read, unread, and
deleted flags are preserved, and the process can be stopped and
resumed. The original messages can optionally be deleted after a
successful transfer.

View File

@ -1,15 +0,0 @@
#
#RELEASE_FOCUS="Initial freshmeat announcement"
#RELEASE_FOCUS="Documentation"
#RELEASE_FOCUS="Code cleanup"
RELEASE_FOCUS="Minor feature enhancements"
#RELEASE_FOCUS="Major feature enhancements"
#RELEASE_FOCUS="Minor bugfixes"
#RELEASE_FOCUS="Major bugfixes"
#RELEASE_FOCUS="Minor security fixes"
#RELEASE_FOCUS="Major security fixes"
#TEXT_BODY="Syntax cleanup"
#TEXT_BODY="Updated documentation"
TEXT_BODY="Several improvements to reach better usability. Authentication cram-md5 is not used by default (too few server support it). Issues from servers changing or adding header are avoided. Now imapsync has a way to handle efficiently no header in messages. The imap server dkimap is supported (dkimap isn't a uid capability server). Added NTLM authentication with domain. Added --minsize option to transfer messages bigger than a given size. Added memory consumption measurement to compute how much concurrent imapsync can run in parallel on a system. Imapsync is no longer gratis from the home page."

View File

@ -1,9 +0,0 @@
{
"release": {
"tag_list": "stable, Minor feature enhancements",
"version": "1.383",
"hidden_from_frontpage": false,
"changelog": "Since last public release 1.350 several improvements have been made to reach a better usability. By default, authentication cram-md5 is not used (too few server support it) so --noauthmd5 option becomes useless. To avoid issues from servers changing or adding header option --useheader Message-Id is on by default too. Now imapsync has a way to handle efficiently no headers in messages (take first 2KB body). The imap server dkimap is now supported (it was not because dkimap is not a uid capability server). NTLM authentication with domain is supported. Added --minsize option to transfer messages bigger than a given size. Added memory consumption measurement to compute how much concurrent imapsync can run in parallel on a system. Imapsync is no longer gratis from the home page. Imapsync license has not changed, it is still a WTFPL software. Thanks again to the freshmeat guy who corrects my bad and poorly English!"
}
}

View File

@ -1,12 +0,0 @@
Project: imapsync
Version: 1.293
Release-Focus: Minor bugfixes
Hide: N
Home-Page-URL: http://www.linux-france.org/prj/imapsync/
Gzipped-Tar-URL: http://www.linux-france.org/prj/imapsync/dist/
Bug fixes.
Many thanks to the freshmeat folk that correct my bad and poorly English !

330
imapsync
View File

@ -20,7 +20,7 @@ Synchronise mailboxes between two imap servers.
Good at IMAP migration. More than 36 different IMAP server softwares
supported with success.
$Revision: 1.411 $
$Revision: 1.422 $
=head1 SYNOPSIS
@ -99,7 +99,7 @@ The option list:
[--minage <int>]
[--skipheader <regex>]
[--useheader <string>] [--useheader <string>]
[--nouid1] [--nouid1]
[--nouid1] [--nouid2]
[--usecache]
[--skipsize] [--allowsizemismatch]
[--delete] [--delete2]
@ -380,10 +380,10 @@ Success stories reported with the following 41 imap servers
- iPlanet Messaging server 4.15, 5.1, 5.2
- IMail 7.15 (Ipswitch/Win2003), 8.12, 11.03 [host1]
- MailEnable 4.23 [host1] [host2]
- MDaemon 7.0.1, 8.0.2, 8.1, 9.5.4 (Windows server 2003 R2 platform)
- MDaemon 7.0.1, 8.0.2, 8.1, 9.5.4 (Windows server 2003 R2 platform), 12 [host2]
- Mercury 4.1 (Windows server 2000 platform)
- Microsoft Exchange Server 5.5, 6.0.6249.0[host1], 6.0.6487.0[host1],
6.5.7638.1 [host2], Exchange 2007 SP1 (with Update Rollup 2),
6.5.7638.1 [host2], 6.5 [host1], Exchange 2007 SP1 (with Update Rollup 2),
Exchange2007-EP-SP2,
Exchange 2010 RTM (Release to Manufacturing) [host2]
- Mirapoint
@ -496,7 +496,7 @@ Entries for imapsync:
Feedback (good or bad) will often be welcome.
$Id: imapsync,v 1.411 2011/04/19 23:34:30 gilles Exp gilles $
$Id: imapsync,v 1.422 2011/05/08 17:21:38 gilles Exp gilles $
=cut
@ -540,13 +540,16 @@ use constant {
my(
$rcs, $pidfile,
$debug, $debugimap, $debugimap1, $debugimap2, $nb_errors,
$debug, $debugimap, $debugimap1, $debugimap2, $debugcontent, $debugflags,
$debugLIST,
$nb_errors,
$host1, $host2, $port1, $port2,
$user1, $user2, $domain1, $domain2,
$password1, $password2, $passfile1, $passfile2,
@folder, @include, @exclude, @folderrec,
$prefix1, $prefix2,
@regextrans2, @regexmess, @regexflag,
@regextrans2, @regexmess, @regexflag,
$flagsCase,
$sep1, $sep2,
$syncinternaldates,
$idatefromheader,
@ -589,6 +592,7 @@ my(
$authmech1, $authmech2,
$split1, $split2,
$reconnectretry1, $reconnectretry2,
$relogin1, $relogin2,
$tests, $test_builder, $tests_debug,
$allow3xx, $justlogin,
$tmpdir,
@ -604,7 +608,7 @@ my(
# global variables initialisation
$rcs = '$Id: imapsync,v 1.411 2011/04/19 23:34:30 gilles Exp gilles $ ';
$rcs = '$Id: imapsync,v 1.422 2011/05/08 17:21:38 gilles Exp gilles $ ';
$total_bytes_transferred = 0;
$total_bytes_skipped = 0;
@ -646,7 +650,14 @@ $pidfile ||= $tmpdir . '/imapsync.pid';
# allow Mail::IMAPClient 3.0.xx by default
$allow3xx = defined($allow3xx) ? $allow3xx : 1;
$takebody = defined($takebody) ? $takebody : 1;
$takebody = defined( $takebody ) ? $takebody : 1;
# turn on RFC standard flags correction like \SEEN -> \Seen
$flagsCase = defined( $flagsCase ) ? $flagsCase : 1 ;
# turn on relogin 5 by default
$relogin1 = defined( $relogin1 ) ? $relogin1 : 5 ;
$relogin2 = defined( $relogin2 ) ? $relogin2 : 5 ;
if ( $fast ) {
# $useuid = 1 ;
@ -718,6 +729,19 @@ if ($delete) {
}
}
if ( $delete2 ) {
if ( ! defined( $expunge2 ) ) {
$expunge2 = 1 ;
}
}
if ( $delete and $delete2 ) {
print "Warning: using --delete and --delete2 is almost always a bad idea, exiting imapsync\n" ;
exit_clean( 0 ) ;
}
if($idatefromheader) {
print "Turned ON idatefromheader, ",
"will set the internal dates on host2 from the 'Date:' header line.\n";
@ -803,15 +827,14 @@ $debugimap1 and print "Host1 connection\n";
$imap1 = login_imap($host1, $port1, $user1, $domain1, $password1,
$debugimap1, $timeout, $fastio1, $ssl1, $tls1,
$authmech1, $authuser1, $reconnectretry1,
$proxyauth1, $uid1);
$proxyauth1, $uid1, $split1);
$debugimap2 and print "Host2 connection\n";
$imap2 = login_imap($host2, $port2, $user2, $domain2, $password2,
$debugimap2, $timeout, $fastio2, $ssl2, $tls2,
$authmech2, $authuser2, $reconnectretry2,
$proxyauth2, $uid2);
$proxyauth2, $uid2, $split2);
# history
$debug and print "Host1 Buffer I/O: ", $imap1->Buffer(), "\n";
$debug and print "Host2 Buffer I/O: ", $imap2->Buffer(), "\n";
@ -829,9 +852,6 @@ print "Host2 capability: ", join(" ", $imap2->capability_update()), "\n";
exit_clean(0) if ($justlogin);
$split1 and $imap1->Split($split1);
$split2 and $imap2->Split($split2);
#
# Folder stuff
#
@ -980,14 +1000,14 @@ print "++++ Looping on each folder\n";
FOLDER: foreach my $h1_fold (@h1_folders_wanted) {
my $h2_fold = imap2_folder_name($h1_fold);
#relogin1( ) if ( $relogin1 ) ;
printf("%-35s -> %-35s\n", "[$h1_fold]", "[$h2_fold]");
select_folder($imap1, $h1_fold, 'Host1') or next FOLDER;
if ( ! exists($h2_folders_all{$h2_fold})) {
create_folder($imap2, $h2_fold, 'Host2') or next FOLDER;
create_folder( $imap2, $h2_fold, $h1_fold ) or next FOLDER;
}
acls_sync($h1_fold, $h2_fold);
@ -998,7 +1018,7 @@ FOLDER: foreach my $h1_fold (@h1_folders_wanted) {
#print "%%% @select_results\n";
my $permanentflags2 = permanentflags(@select_results);
$debug and print "permanentflags: $permanentflags2\n" ;
if ($expunge){
if ( $expunge or $expunge1 ){
print "Expunging host1 $h1_fold\n";
unless($dry) { $imap1->expunge() };
#print "Expunging host2 $h2_fold\n";
@ -1014,12 +1034,12 @@ FOLDER: foreach my $h1_fold (@h1_folders_wanted) {
my @h1_msgs = select_msgs($imap1);
$debug and print "LIST Host1: ", scalar(@h1_msgs), " messages [@h1_msgs]\n";
( $debug or $debugLIST ) and print "LIST Host1: ", scalar(@h1_msgs), " messages [@h1_msgs]\n";
# internal dates on host2 are after the ones on host1
# normally...
my @h2_msgs = select_msgs($imap2);
$debug and print "LIST Host2: ", scalar(@h2_msgs), " messages [@h2_msgs]\n";
( $debug or $debugLIST ) and print "LIST Host2: ", scalar(@h2_msgs), " messages [@h2_msgs]\n";
my $cache_base = "$tmpdir/imapsync_cache/$host1/$user1/$host2/$user2";
my $cache_dir = cache_folder( $cache_base, $h1_fold, $h2_fold );
@ -1052,9 +1072,11 @@ FOLDER: foreach my $h1_fold (@h1_folders_wanted) {
delete @h2_msgs_no_cache{ @h2_msgs_in_cache } ;
my @h1_msgs_no_cache = keys %h1_msgs_no_cache ;
#print "h1_msgs_no_cache: [@h1_msgs_no_cache]\n" ;
my @h2_msgs_no_cache = keys %h2_msgs_no_cache ;
my @h2_msgs_delete2_no_cache = () ;
%h1_msgs_copy_by_uid = ( ) ;
if ( $useuid ) {
# use uid so we have to avoid getting header
@ -1184,6 +1206,10 @@ FOLDER: foreach my $h1_fold (@h1_folders_wanted) {
print "uidexpunge $cnt message(s)\n";
$imap2->uidexpunge(\@h2_expunge) if !$dry;
}
if ($expunge2){
print "Expunging host2 folder $h2_fold\n";
unless($dry) { $imap2->expunge() };
}
}
my $h2_uidnext = $imap2->uidnext( $h2_fold ) ;
@ -1192,19 +1218,6 @@ FOLDER: foreach my $h1_fold (@h1_folders_wanted) {
my $h1_size = $h1_hash{$m_id}{'s'};
my $h1_msg = $h1_hash{$m_id}{'m'};
my $h1_idate = $h1_hash{$m_id}{'D'};
if (defined $maxsize and $h1_size >= $maxsize) {
print "msg $h1_fold/$h1_msg skipping ($h1_size exceeds maxsize limit $maxsize bytes)\n";
$total_bytes_skipped += $h1_size;
$nb_msg_skipped += 1;
next MESS;
}
if (defined $minsize and $h1_size <= $minsize) {
print "msg $h1_fold/$h1_msg skipping ($h1_size smaller than minsize $minsize bytes)\n";
$total_bytes_skipped += $h1_size;
$nb_msg_skipped += 1;
next MESS;
}
unless (exists($h2_hash{$m_id})) {
# copy
@ -1224,7 +1237,7 @@ FOLDER: foreach my $h1_fold (@h1_folders_wanted) {
#$debug and print "MESSAGE $m_id\n";
my $h2_msg = $h2_hash{$m_id}{'m'};
sync_flags( $h1_msg, $h2_msg, $h2_fold, $permanentflags2, $h1_fir_ref, $h2_fir_ref ) ;
sync_flags( $h1_fold, $h1_msg, $h2_fold, $h2_msg, $permanentflags2, $h1_fir_ref, $h2_fir_ref ) ;
# Good
my $h2_size = $h2_hash{$m_id}{'s'};
@ -1235,7 +1248,7 @@ FOLDER: foreach my $h1_fold (@h1_folders_wanted) {
unless( $dry ) {
$imap1->delete_message( $h1_msg );
$h1_nb_msg_deleted += 1;
$imap1->expunge() if ( $expunge );
$imap1->expunge() if ( $expunge or $expunge1 );
}
}
@ -1244,20 +1257,21 @@ FOLDER: foreach my $h1_fold (@h1_folders_wanted) {
MESS_IN_CACHE: foreach my $h1_msg ( @h1_msgs_in_cache ) {
my $h2_msg = $cache_1_2_ref->{ $h1_msg } ;
$debugcache and print "cache messages update $h1_msg->$h2_msg\n";
sync_flags( $h1_msg, $h2_msg, $h2_fold, $permanentflags2, $h1_fir_ref, $h2_fir_ref ) ;
sync_flags( $h1_fold, $h1_msg, $h2_fold, $h2_msg, $permanentflags2, $h1_fir_ref, $h2_fir_ref ) ;
my $h1_size = $h1_fir_ref->{ $h1_msg }->{ 'RFC822.SIZE' } ;
$total_bytes_skipped += $h1_size;
$nb_msg_skipped += 1;
}
#print "Messages by uid: ", map { "$_ " } keys %h1_msgs_copy_by_uid, "\n" ;
MESS_BY_UID: foreach my $h1_msg ( sort { $a <=> $b } keys %h1_msgs_copy_by_uid ) {
# copy_message
#print "Copy by uid $h1_fold/$h1_msg\n" ;
$debug and print "Copy by uid $h1_fold/$h1_msg\n" ;
copy_message( $h1_msg, $h1_fold, $h2_fold, $h1_fir_ref, $permanentflags2, $cache_dir ) ;
}
if ($expunge1){
if ($expunge or $expunge1){
print "Expunging host1 folder $h1_fold\n";
unless($dry) { $imap1->expunge() };
}
@ -1269,18 +1283,34 @@ FOLDER: foreach my $h1_fold (@h1_folders_wanted) {
$debug and print "Time: ", timenext(), " s\n";
}
sub size_filtered_flag {
my( $h1_size ) = @_ ;
if (defined $maxsize and $h1_size >= $maxsize) {
return( 1 ) ;
}
if (defined $minsize and $h1_size <= $minsize) {
return( 1 ) ;
}
return( 0 ) ;
}
sub sync_flags {
my ( $h1_msg, $h2_msg, $h2_fold, $permanentflags2, $h1_fir_ref, $h2_fir_ref ) = @_ ;
$debug and print "sync flags $h1_msg->$h2_msg\n";
my ( $h1_fold, $h1_msg, $h2_fold, $h2_msg, $permanentflags2, $h1_fir_ref, $h2_fir_ref ) = @_ ;
$debug and print "sync flags $h1_fold/$h1_msg->$h2_fold/$h2_msg\n";
my $h1_size = $h1_fir_ref->{$h1_msg}->{"RFC822.SIZE"} ;
return() if size_filtered_flag( $h1_size ) ;
# used cached flag values for efficiency
my $h1_flags = $h1_fir_ref->{ $h1_msg }->{ "FLAGS" } ;
my $h2_flags = $h2_fir_ref->{ $h2_msg }->{ "FLAGS" } ;
# RFC 2060: This flag can not be altered by any client
$h1_flags =~ s@\\Recent\s?@@gi;
$h1_flags = flags_regex($h1_flags) if @regexflag;
$h1_flags = flags_filter($h1_flags, $permanentflags2) if ( $permanentflags2 );
$h1_flags =~ s@\\Recent\s?@@gi ;
$h1_flags = flags_regex( $h1_flags ) if @regexflag;
$h1_flags = flagsCase( $h1_flags ) if $flagsCase ;
$h1_flags = flags_filter( $h1_flags, $permanentflags2) if ( $permanentflags2 ) ;
# compare flags - set flags if there a difference
my @h1_flags = sort split(' ', $h1_flags );
@ -1288,7 +1318,9 @@ sub sync_flags {
my $diff = compare_lists( \@h1_flags, \@h2_flags );
#$diff = 1 ;
$diff and $debug and print "msg $h2_fold/$h2_msg replacing h2 flags( $h2_flags ) with h1 flags( $h1_flags )\n";
$debugflags and print "msg h1 $h1_fold/$h1_msg flags( $h1_flags ) h2 $h2_fold/$h2_msg flags( $h2_flags )\n" ;
$diff and ( $debug or $debugflags )
and print "msg $h2_fold/$h2_msg replacing h2 flags( $h2_flags ) with h1 flags( $h1_flags )\n";
# This sets flags so flags can be removed with this
# When you remove a \Seen flag on host1 you want to it
# to be removed on host2. Just add flags is not what
@ -1546,12 +1578,52 @@ sub justconnect {
}
sub relogin1 {
$imap1 = relogin_imap(
$imap1,
$host1, $port1, $user1, $domain1, $password1,
$debugimap1, $timeout, $fastio1, $ssl1, $tls1,
$authmech1, $authuser1, $reconnectretry1,
$proxyauth1, $uid1, $split1) ;
$relogin1-- if ( $relogin1 ) ;
}
sub relogin2 {
$imap2 = relogin_imap(
$imap2,
$host2, $port2, $user2, $domain2, $password2,
$debugimap2, $timeout, $fastio2, $ssl2, $tls2,
$authmech2, $authuser2, $reconnectretry2,
$proxyauth2, $uid2, $split2) ;
$relogin2-- if ( $relogin2 ) ;
}
sub relogin_imap {
my($imap,
$host, $port, $user, $domain, $password,
$debugimap, $timeout, $fastio,
$ssl, $tls, $authmech, $authuser, $reconnectretry,
$proxyauth, $uid, $split) = @_;
my $folder_current = $imap->Folder ;
$imap->logout( ) ;
$imap = login_imap(
$host, $port, $user, $domain, $password,
$debugimap, $timeout, $fastio,
$ssl, $tls, $authmech, $authuser, $reconnectretry,
$proxyauth, $uid, $split
) ;
$imap->select( $folder_current ) if defined( $folder_current ) ;
return( $imap ) ;
}
sub login_imap {
my($host, $port, $user, $domain, $password,
$debugimap, $timeout, $fastio,
$ssl, $tls, $authmech, $authuser, $reconnectretry,
$proxyauth, $uid) = @_;
$proxyauth, $uid, $split ) = @_;
my ($imap);
$imap = Mail::IMAPClient->new();
@ -1626,7 +1698,8 @@ sub login_imap {
die_clean("$info [LOGIN]: ", $imap->LastError, "\n");
}
$proxyauth && $imap->proxyauth($user);
$split and $imap->Split( $split ) ;
print "Success login on [$host] with user [$user] auth [$authmech]\n";
return($imap);
}
@ -1654,8 +1727,8 @@ sub banner_imapsync {
my @argv_copy = @_;
my $banner_imapsync = join("",
'$RCSfile: imapsync,v $ ',
'$Revision: 1.411 $ ',
'$Date: 2011/04/19 23:34:30 $ ',
'$Revision: 1.422 $ ',
'$Date: 2011/05/08 17:21:38 $ ',
"\n",localhost_info(), "\n",
"Command line used:\n",
"$0 ", command_line_nopassword(@argv_copy), "\n",
@ -1724,13 +1797,19 @@ sub select_folder {
sub create_folder {
my ($imap, $folder, $hostside) = @_;
print "$hostside folder $folder does not exist\n";
print "Creating folder [$folder]\n";
if ( ! $dry){
if ( ! $imap->create($folder)){
warn "Couldn't create [$folder] on $hostside: ",
$imap->LastError,"\n";
my( $imap2, $h2_fold, $h1_fold ) = @_ ;
if ( $imap2->exists( $h2_fold ) ) {
print "Folder $h2_fold already exists on host2.\n";
return( 1 ) ;
}else{
print "Folder $h2_fold does not exist on host2.\n";
}
print "Creating folder [$h2_fold] on host2.\n";
if ( ! $dry ){
if ( ! $imap2->create($h2_fold)){
warn "Couldn't create folder [$h2_fold] from [$h1_fold]: ",
$imap2->LastError,"\n";
$nb_errors++;
return(0);
}else{
@ -2197,10 +2276,10 @@ sub flags_regex {
my ($h1_flags) = @_;
foreach my $regexflag (@regexflag) {
my $h1_flags_orig = $h1_flags;
$debug and print "eval \$h1_flags =~ $regexflag\n";
$debugflags and print "eval \$h1_flags =~ $regexflag\n";
eval("\$h1_flags =~ $regexflag");
die_clean("error: eval regexflag '$regexflag': $@\n") if $@;
$debug and print "regexflag $regexflag [$h1_flags_orig] -> [$h1_flags]\n";
$debugflags and print "regexflag $regexflag [$h1_flags_orig] -> [$h1_flags]\n";
}
return($h1_flags);
}
@ -2284,7 +2363,51 @@ sub flags_filter {
return($flags_out);
}
sub flagsCase {
my $flags = shift ;
my @flags = split( /\s+/, $flags );
my %rfc_flags = map { $_ => 1 } split(' ', '\Answered \Flagged \Deleted \Seen \Draft' );
my @flags_out = map { exists $rfc_flags{ ucsecond( lc( $_ ) ) } ? ucsecond( lc( $_ ) ) : $_ } @flags ;
my $flags_out = join( ' ', @flags_out ) ;
#print "%%%$flags_out%%%\n" ;
return( $flags_out ) ;
}
sub tests_flagsCase {
ok( '\Seen' eq flagsCase( '\Seen' ), 'flagsCase: \Seen -> \Seen' ) ;
ok( '\Seen' eq flagsCase( '\SEEN' ), 'flagsCase: \SEEN -> \Seen' ) ;
ok( '\Seen \Draft' eq flagsCase( '\SEEN \DRAFT' ), 'flagsCase: \SEEN \DRAFT -> \Seen \Draft' ) ;
ok( '\Draft \Seen' eq flagsCase( '\DRAFT \SEEN' ), 'flagsCase: \DRAFT \SEEN -> \Draft \Seen' ) ;
ok( '\Draft LALA \Seen' eq flagsCase( '\DRAFT LALA \SEEN' ), 'flagsCase: \DRAFT LALA \SEEN -> \Draft LALA \Seen' ) ;
ok( '\Draft lala \Seen' eq flagsCase( '\DRAFT lala \SEEN' ), 'flagsCase: \DRAFT lala \SEEN -> \Draft lala \Seen' ) ;
}
sub ucsecond {
my $string = shift ;
my $output ;
return( $string ) if ( 1 >= length( $string ) ) ;
$output = substr( $string, 0, 1) . uc( substr( $string, 1, 1 ) ) if ( 2 == length( $string ) ) ;
$output = substr( $string, 0, 1) . uc( substr( $string, 1, 1 ) ) . substr( $string, 2 );
#print "UUU $string -> $output\n" ;
return( $output ) ;
}
sub tests_ucsecond {
ok( 'aBcde' eq ucsecond( 'abcde' ), 'ucsecond: abcde -> aBcde' ) ;
ok( 'ABCDE' eq ucsecond( 'ABCDE' ), 'ucsecond: ABCDE -> ABCDE' ) ;
ok( 'ABCDE' eq ucsecond( 'AbCDE' ), 'ucsecond: AbCDE -> ABCDE' ) ;
ok( 'ABCde' eq ucsecond( 'AbCde' ), 'ucsecond: AbCde -> ABCde' ) ;
ok( 'A' eq ucsecond( 'A' ), 'ucsecond: A -> A' ) ;
ok( 'AB' eq ucsecond( 'Ab' ), 'ucsecond: Ab -> AB' ) ;
ok( '\B' eq ucsecond( '\b' ), 'ucsecond: \b -> \B' ) ;
ok( '\Bcde' eq ucsecond( '\bcde' ), 'ucsecond: \bcde -> \Bcde' ) ;
}
sub select_msgs {
my ($imap) = @_;
@ -2346,24 +2469,53 @@ sub lastuid {
return( $lastuid ) ;
}
sub size_filtered {
my( $h1_size, $h1_msg, $h1_fold, $h2_fold ) = @_ ;
if (defined $maxsize and $h1_size >= $maxsize) {
print "msg $h1_fold/$h1_msg skipped ($h1_size exceeds maxsize limit $maxsize bytes)\n";
$total_bytes_skipped += $h1_size;
$nb_msg_skipped += 1;
return( 1 ) ;
}
if (defined $minsize and $h1_size <= $minsize) {
print "msg $h1_fold/$h1_msg skipped ($h1_size smaller than minsize $minsize bytes)\n";
$total_bytes_skipped += $h1_size;
$nb_msg_skipped += 1;
return( 1 ) ;
}
return( 0 ) ;
}
sub copy_message {
# copy
my ( $h1_msg, $h1_fold, $h2_fold, $h1_fir_ref, $permanentflags2, $cache_dir ) = @_ ;
$debug and print "msg $h1_fold/$h1_msg copying to $h2_fold\n";
my $h1_size = $h1_fir_ref->{$h1_msg}->{"RFC822.SIZE"};
my $h1_flags = $h1_fir_ref->{$h1_msg}->{"FLAGS"};
my $h1_idate = $h1_fir_ref->{$h1_msg}->{"INTERNALDATE"};
my $h1_size = $h1_fir_ref->{$h1_msg}->{"RFC822.SIZE"} || '' ;
my $h1_flags = $h1_fir_ref->{$h1_msg}->{"FLAGS"} || '' ;
my $h1_idate = $h1_fir_ref->{$h1_msg}->{"INTERNALDATE"} || '' ;
return() if size_filtered( $h1_size, $h1_msg, $h1_fold, $h2_fold ) ;
my $string;
#print "SLEEP 5\n" and sleep 5 ;
print "- msg $h1_fold/$h1_msg S[$h1_size] F[$h1_flags] I[$h1_idate] has RFC822.SIZE null!\n" if ( ! $h1_size ) ;
$string = $imap1->message_string($h1_msg);
unless (defined($string)) {
my $string_len = defined( $string ) ? length( $string ) : '' ; # length or undef
#print "- msg $h1_fold/$h1_msg {$string_len}\n" ;
unless ( defined( $string ) and $string_len ) { # undef or 0 length
warn
"- msg $h1_fold/$h1_msg could not be fetched: ",
$imap1->LastError, "\n";
$nb_errors++;
$total_bytes_error += $h1_size;
"- msg $h1_fold/$h1_msg {$string_len} S[$h1_size] F[$h1_flags] I[$h1_idate] could not be fetched: ",
$imap1->LastError, "\n" ;
$nb_errors++ ;
$total_bytes_error += $h1_size if ( $h1_size ) ;
#relogin1( ) if ( $relogin1 ) ;
return( ) ;
}
@ -2371,7 +2523,7 @@ sub copy_message {
$string = regexmess($string);
}
$debug and print
$debugcontent and print
"=" x80, "\n",
"F message content begin next line\n",
$string,
@ -2395,7 +2547,7 @@ sub copy_message {
# RFC 2060: This flag can not be altered by any client
$h1_flags =~ s@\\Recent\s?@@gi;
$h1_flags = flags_regex($h1_flags) if @regexflag;
$h1_flags = flagsCase( $h1_flags ) if $flagsCase ;
$h1_flags = flags_filter($h1_flags, $permanentflags2) if ($permanentflags2);
my $new_id;
@ -2407,7 +2559,7 @@ sub copy_message {
$new_id = $imap2->append_string($h2_fold, $string, $h1_flags, $h1_date);
unless($new_id){
no warnings 'uninitialized';
warn "- msg $h1_fold/$h1_msg couldn't append (Subject:[".
warn "- msg $h1_fold/$h1_msg {$string_len} couldn't append (Subject:[".
$imap1->subject($h1_msg)."]) to folder $h2_fold: ",
$imap2->LastError, "\n";
$nb_errors++;
@ -2418,16 +2570,10 @@ sub copy_message {
# good
# $new_id is an id if the IMAP server has the
# UIDPLUS capability else just a ref
if ( $new_id !~ m{^\d+$} ) {
$new_id = lastuid( $imap2, $h2_fold, $h2_uidguess ) ;
}
printf( "msg %s/%-10s copied to %s/%-10s\n", $h1_fold, $h1_msg, $h2_fold, $new_id );
printf( "msg %s/%-19s copied to %s/%-10s\n", $h1_fold, "$h1_msg {$string_len}", $h2_fold, $new_id );
$h2_uidguess++;
$total_bytes_transferred += $h1_size;
$nb_msg_transferred += 1;
@ -2438,9 +2584,10 @@ sub copy_message {
unless($dry) {
$imap1->delete_message($h1_msg);
$h1_nb_msg_deleted += 1;
$imap1->expunge() if ($expunge);
$imap1->expunge() if ( $expunge or $expunge1 );
}
}
#print "PRESS ENTER" and my $a = <> ;
}
}
else{
@ -2951,10 +3098,13 @@ sub get_options {
exit 1;
}
my $opt_ret = GetOptions(
"debug!" => \$debug,
"debugimap!" => \$debugimap,
"debugimap1!" => \$debugimap1,
"debugimap2!" => \$debugimap2,
"debug!" => \$debug,
"debugLIST!" => \$debugLIST,
"debugcontent!" => \$debugcontent,
"debugflags!" => \$debugflags,
"debugimap!" => \$debugimap,
"debugimap1!" => \$debugimap1,
"debugimap2!" => \$debugimap2,
"host1=s" => \$host1,
"host2=s" => \$host2,
"port1=i" => \$port1,
@ -2981,6 +3131,7 @@ sub get_options {
"regextrans2=s" => \@regextrans2,
"regexmess=s" => \@regexmess,
"regexflag=s" => \@regexflag,
"flagsCase!" => \$flagsCase,
"delete!" => \$delete,
"delete2!" => \$delete2,
"delete2folders!" => \$delete2folders,
@ -3028,12 +3179,14 @@ sub get_options {
"authuser1=s" => \$authuser1,
"authuser2=s" => \$authuser2,
"proxyauth1" => \$proxyauth1,
"proxyauth2" => \$proxyauth1,
"proxyauth2" => \$proxyauth2,
"split1=i" => \$split1,
"split2=i" => \$split2,
"buffersize=i" => \$buffersize,
"reconnectretry1=i" => \$reconnectretry1,
"reconnectretry2=i" => \$reconnectretry2,
"relogin1=i" => \$relogin1,
"relogin2=i" => \$relogin2,
"tests" => \$tests,
"tests_debug" => \$tests_debug,
"allow3xx!" => \$allow3xx,
@ -3222,7 +3375,7 @@ sub check_last_release {
}
sub imapsync_version {
my $rcs = '$Id: imapsync,v 1.411 2011/04/19 23:34:30 gilles Exp gilles $ ';
my $rcs = '$Id: imapsync,v 1.422 2011/05/08 17:21:38 gilles Exp gilles $ ';
$rcs =~ m/,v (\d+\.\d+)/;
my $VERSION = ($1) ? $1: "UNKNOWN";
return($VERSION);
@ -3469,6 +3622,8 @@ Several options are mandatory.
--useuid : Use uid instead of header as a criterium to sync.
--usecache is then implied unless --nousecache
--debug : debug mode.
--debugcontent : debug content of the messages transfered.
--debugflags : debug flags.
--debugimap1 : imap debug mode for host1. imap debug is very verbose.
--debugimap2 : imap debug mode for host2.
--debugimap : imap debug mode for host1 and host2.
@ -3730,11 +3885,7 @@ sub tests_debug {
SKIP: {
skip "No test in normal run" if ( not $tests_debug );
tests_clean_cache( ) ;
tests_match_a_cache_file( ) ;
tests_touch( ) ;
tests_cache_map( ) ;
tests_get_cache( ) ;
tests_flagsCase( ) ;
}
}
@ -3747,7 +3898,7 @@ sub tests {
tests_regexmess();
tests_flags_regex();
tests_permanentflags();
tests_flags_filter();
tests_flags_filter( ) ;
tests_imap2_folder_name();
tests_command_line_nopassword();
tests_good_date();
@ -3763,6 +3914,8 @@ sub tests {
tests_clean_cache( ) ;
tests_match_a_cache_file( ) ;
tests_touch( ) ;
tests_ucsecond( ) ;
}
}
@ -4737,7 +4890,6 @@ sub Reconnect_counter {
$self->{Reconnect_counter} = 0 if ( not defined( $self->{Reconnect_counter} ) ) ;
if (@_) { $self->{Reconnect_counter} = shift }
return $self->{Reconnect_counter};
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

Binary file not shown.

View File

@ -5,7 +5,7 @@
<title>Imapsync: an IMAP migration tool ( release <!--#exec cmd="cat VERSION"--> )</title>
<meta name="generator" content="Bluefish 1.0.7"/>
<meta name="author" content="Gilles LAMIRAL"/>
<meta name="date" content="2011-04-20T01:50:31+0200"/>
<meta name="date" content="2011-05-09T02:42:11+0200"/>
<meta name="copyright" content="None"/>
<meta name="keywords" content="imap, transfert, migration"/>
<meta name="description" content="imap migration tool"/>
@ -66,21 +66,39 @@ where the user plays independently on both sides. Use <b>offlineimap</b>
<p>Written on <!--#flastmod file="VERSION" --></p>
<p>See <a href="ChangeLog">ChangeLog</a> to know what's new in details.</p>
<p>See <b><a href="ChangeLog">ChangeLog</a></b> to know what's new in details since 2001.</p>
<p>New features since previous releases 1.404:</p>
<p>New features or bugfixes since previous release 1.411:</p>
<ul>
<li>Updated imapsync.exe to last <b>Mail-IMAPClient 3.28</b> (thanks to Phil Pearl Lobbes)</li>
<li>Option <b>--useuid</b> now works also with <b>--delete2</b> option.</li>
<li><b>Better default behavior</b>: Option --delete2 implies --expunge2 now (unless --noexpunge2 is given.)</li>
<li><b>Better default behavior</b>: Correct flags case to be RFC compliant on host2 if host1 is not (\SEEN -> \Seen)</li>
<li><b>Better debug</b>: Added --debugcontent option to avoid debugging content (can be big) with --debug option.</li>
<li><b>Better debug</b>: Added --debugflags to permit flag debugging only.</li>
<li><b>Bugfix</b>: The APPEND error then the FETCH 0 byte error is fixed</li>
<li><b>Bugfix</b>: Options --maxsize --minsize now work with --useuid</li>
<li><b>Bugfix</b>: Flag sync of already transfered messages now take care of --maxsize --minsize options</li>
<li><b>Bugfix</b>: Added 0 length message tracking when fetching host1 (to avoid frequently "APPEND {0}" recent issues).</li>
<li><b>Bugfix</b>: Avoid now Inbox <-> INBOX problem ("already exists").</li>
<li><b>Bugfix</b>: --proxyauth2 was setting proxyauth1 instead of proxyauth2</li>
</ul>
<!--
<p>The next imapsync release should see:</p>
<ul>
<li>An option to sync to and from files (local backup)</li>
<li>nothing planned</li>
</ul>
-->
<h2><a id="NUMBERS"></a>Some numbers</h2>
<ul>
<li>Number of <b>imapsync users</b> per month: between <b>2 and 3 thousands </b>users</li>
<li>Number of <b>imapsync transfers</b> per month: between <b>3 and 8 millions </b>transfers</li>
<li>Pourcentage of <b>MSWin32</b> users : <b>10%</b></li>
<li><b>Biggest user</b> usage: <b>5 millions</b> of transfers in a month (one every 2 seconds)</li>
</ul>
<h2><a id="AUTHOR"></a>Who is the author?</h2>
<p>Gilles LAMIRAL<br/>
@ -126,7 +144,7 @@ The Perl <b>imapsync</b> source code will run anywhere a <b>Perl interpreter can
<p>You will receive a download link <b>just after</b> the payment.<br/>
<b>30 days money-back guarantee!</b></p>
<h2><a id="buy_exe"></a>Standalone imapsync.exe for win32</h2>
<h2><a id="buy_exe"></a>Buy standalone imapsync.exe for win32</h2>
<p>Struggle free from source code and Perl installation by<br/>
buying the latest win32 <b>standalone imapsync.exe</b> for <b>30 EUR</b></p>
@ -162,12 +180,12 @@ thanks to Strawberry Perl 5.12 and Par::Packer module.<br/>
The build system for imapsync.exe is XP Pro SP2 on a Intel Celeron 400 MHz 256 Mo RAM. </p>
-->
<h2><a id="buy_support"></a>Support for imapsync</h2>
<h2><a id="buy_support"></a>Buy professional support for imapsync</h2>
<p>For <b>90 EUR</b> buy imapsync <b>support</b> by the developper who wrote and maintains imapsync.
<p>For <b>60 EUR</b> buy imapsync <b>support</b> by the developper who wrote and maintains imapsync.
</p>
<p>
90 EUR is equal to around <b>125 USD</b>, no problem to pay in USD (or any currency) with paypal:
60 EUR is equal to around <b>80 USD</b>, no problem to pay in USD (or any currency) with paypal:
</p>
<form action="https://www.paypal.com/cgi-bin/webscr" method="post">
@ -183,7 +201,6 @@ The build system for imapsync.exe is XP Pro SP2 on a Intel Celeron 400 MHz 256 M
</p>
</form>
<p>Then you will be able to expose your issues by email or phone and to converse until your issues are solved.
</p>
@ -333,7 +350,7 @@ will be to code it or fix it.<br/>
v2.3.7,
(http://asg.web.cmu.edu/cyrus/)
</li>
<li>David Tobit V8 (proprietary Message system).</li>
<li>David Tobit V8.</li>
<li>DBMail 1.2.1, 2.0.4, 2.0.9, 2.2rc1 (GPL) (http://www.dbmail.org/).
2.0.7 seems buggy.</li>
<li>Deerfield VisNetic MailServer 5.8.6 [host1]</li>
@ -344,16 +361,16 @@ will be to code it or fix it.<br/>
<li>Eudora WorldMail v2</li>
<li>Gimap (Gmail imap) [host1] [host2]</li>
<li>GMX IMAP4 StreamProxy.</li>
<li>Goddy IMAP (since Goddy runs Courier)</li>
<li>Godaddy IMAP (since Godaddy runs Courier)</li>
<li>Groupwise IMAP (Novell) 6.x and 7.0. Buggy so see the FAQ.</li>
<li>hMailServer 5.3.3 [host2], 4.4.1 [host1], HMAILSERVER 5.3.2-B1769 on windows 2003 [hsot2]</li>
<li>iPlanet Messaging server 4.15, 5.1, 5.2</li>
<li>IMail 7.15 (Ipswitch/Win2003), 8.12, 11.03 [host1]</li>
<li>MailEnable 4.23 [host1] [host2]</li>
<li>MDaemon 7.0.1, 8.0.2, 8.1, 9.5.4 (Windows server 2003 R2 platform)</li>
<li>MDaemon 7.0.1, 8.0.2, 8.1, 9.5.4 (Windows server 2003 R2 platform), 12 [host2]</li>
<li>Mercury 4.1 (Windows server 2000 platform)</li>
<li>Microsoft Exchange Server 5.5, 6.0.6249.0[host1], 6.0.6487.0[host1],
6.5.7638.1 [host2], Exchange 2007 SP1 (with Update Rollup 2),
6.5.7638.1 [host2], 6.5 [host1], Exchange 2007 SP1 (with Update Rollup 2),
Exchange2007-EP-SP2,
Exchange 2010 RTM (Release to Manufacturing) [host2]</li>
<li>Mirapoint server</li>
@ -404,7 +421,7 @@ alt="Viewable With Any Browser" />
<!--#config timefmt="%D" -->
<!--#config timefmt="%A %B %d, %Y" -->
<b>This document last modified on <!--#echo var="LAST_MODIFIED" --></b>
($Id: index.shtml,v 1.63 2011/04/19 23:51:09 gilles Exp gilles $)
($Id: index.shtml,v 1.66 2011/05/09 00:45:40 gilles Exp gilles $)
</p>
</body>

View File

@ -1,16 +0,0 @@
Begin4
Title: imapsync
Version: 1.209
Entered-date: 2007-01-09
Description: IMAP synchronisation, sync, copy or migration tool.
Synchronise mailboxes between two imap servers. Good at IMAP migration.
More than 32 different IMAP server softwares supported with success.
Keywords: IMAP synchronisation mail
Author: lamiral@linux-france.org (Gilles LAMIRAL)
Maintained-by: lamiral@linux-france.org (Gilles LAMIRAL)
Primary-site: http://www.linux-france.org/prj/imapsync/dist/
Alternate-site:
Original-site: http://www.linux-france.org/prj/imapsync/dist/
Platforms: UNIX Windows
Copying-policy: GPL
End

40
memo
View File

@ -1,6 +1,6 @@
#!/bin/sh
# $Id: memo,v 1.30 2011/03/23 19:14:37 gilles Exp gilles $
# $Id: memo,v 1.31 2011/05/07 02:30:54 gilles Exp gilles $
software_version() {
@ -24,7 +24,45 @@ tail -f /usr/local/apache/logs/access_log|cat -n|grep prj/imapsync/VERSION|cat -
EOFF
}
statistics_VERSION() {
TMPDIR=.
export TMPDIR
echo statistics_VERSION_getstats
statistics_VERSION_getstats() {
for f in /home/lf/backuplog/linux-france.org.??-??-2011.bz2; do
b=`basename "$f" .bz2`
echo "$b"
test -f ${b}.imapsync_VERSION && continue
echo NOT DONE ${b}.imapsync_VERSION
bzip2 -dc "$f" | grep -h /prj/imapsync/VERSION > ${b}.imapsync_VERSION
done
}
echo statistics_VERSION_monthly_ip
statistics_VERSION_monthly_ip() {
month=$1
cut -d ' ' -f 1,12,13,18,19 linux-france.org.??-${month}-2011.imapsync_VERSION |sort -n |uniq -c|sort -n > stats_imapsync_2011_${month}.ip
}
echo statistics_VERSION_monthly_ip_wc
statistics_VERSION_monthly_ip_wc() {
month=$1
test -f stats_imapsync_2011_${month}.ip || statistics_VERSION_monthly_ip $month
wc -l stats_imapsync_2011_${month}.ip
}
echo statistics_VERSION_monthly_runs
statistics_VERSION_monthly_runs() {
month=$1
test -f stats_imapsync_2011_${month}.runs || wc -l linux-france.org.??-${month}-2011.imapsync_VERSION > stats_imapsync_2011_${month}.runs
cat stats_imapsync_2011_${month}.runs
}
}
niouzes_compil() {
(

View File

@ -36,7 +36,7 @@ border:0px;
<h1>imapsync donation</h1>
<p>Help the author to maintain imapsync:<br/>
(<b>1 EUR ~ 1.3 USD</b> on 01/2011)
(<b>1 EUR ~ 1.5 USD</b> on 05/2011)
</p>
<form action="https://www.paypal.com/cgi-bin/webscr" method="post">
<p>
@ -65,7 +65,7 @@ border:0px;
<!--#config timefmt="%D" -->
<!--#config timefmt="%A %B %d, %Y" -->
<b>This document last modified on <!--#echo var="LAST_MODIFIED" --></b>
($Id: paypal.shtml,v 1.4 2011/01/18 02:54:01 gilles Exp gilles $)
($Id: paypal.shtml,v 1.5 2011/05/07 02:23:32 gilles Exp gilles $)
</p>
</body>

View File

@ -1,13 +0,0 @@
#!/usr/bin/perl -w
# $Id: 8859_utf8,v 1.1 2010/10/01 13:00:09 gilles Exp gilles $
use Unicode::MapUTF8 qw(to_utf8 from_utf8 utf8_supported_charset);
die unless (utf8_supported_charset('ISO-8859-1'));
while (<>) {
print to_utf8({ -string => $_, -charset => 'ISO-8859-1' });
}

View File

@ -1,6 +0,0 @@
Rewrite all with less scripts
use Email::Simple module

View File

@ -1,147 +0,0 @@
#!/bin/sh
# $Id: memo,v 1.3 2011/03/28 02:14:47 gilles Exp gilles $
echo paypal_bilan_tests_refact_2
paypal_bilan_tests_refact_2() {
# DID output no diff between paypal_bilan_1.22 and 1.23
(
set -x
for f in /g/paypal/paypal_201?_??_complet.csv; do
fb=`basename "$f"`
f1=/g/var/paypal_bilan/tests/${fb}_1.22.out1
f2=/g/var/paypal_bilan/tests/${fb}_1.22.out2
rm "$f2"
/g/public_html/imapsync/paypal_reply/paypal_bilan_1.22 \
--bnc --debug --debug_csv "$f" \
> "$f1"
/g/public_html/imapsync/paypal_reply/paypal_bilan \
--bnc --debug --debug_csv "$f" \
> "$f2"
echo diff "$f1" "$f2"
diff "$f1" "$f2"
done
for f in /g/paypal/paypal_201?_??_complet.csv; do
fb=`basename "$f"`
f1=/g/var/paypal_bilan/tests/${fb}_tva.out1
f2=/g/var/paypal_bilan/tests/${fb}_tva.out2
rm "$f2"
/g/public_html/imapsync/paypal_reply/paypal_bilan_1.22 \
"$f" \
> "$f1"
/g/public_html/imapsync/paypal_reply/paypal_bilan \
"$f" \
> "$f2"
echo diff "$f1" "$f2"
diff "$f1" "$f2"
done
)
}
#echo paypal_bilan_tests_refact_1
paypal_bilan_tests_refact_1() {
# DID output no diff between paypal_bilan_1.11 and 1.13
(
#set -x
for f in /g/paypal/paypal_201?_??.csv; do
fb=`basename "$f"`
f1=/g/var/paypal_bilan/tests/$fb.out1
f2=/g/var/paypal_bilan/tests/$fb.out2
rm "$f2"
/g/public_html/imapsync/paypal_reply/paypal_bilan_1.11 \
--bnc --debug "$f" \
> "$f1"
/g/public_html/imapsync/paypal_reply/paypal_bilan \
--bnc --debug "$f" \
> "$f2"
echo diff "$f1" "$f2"
diff "$f1" "$f2"
done
for f in /g/paypal/paypal_201?_??.csv; do
fb=`basename "$f"`
f1=/g/var/paypal_bilan/tests/$fb.out1
f2=/g/var/paypal_bilan/tests/$fb.out2_usd_eur
rm "$f2"
/g/public_html/imapsync/paypal_reply/paypal_bilan_1.11 \
--bnc --debug "$f" \
> "$f1"
/g/public_html/imapsync/paypal_reply/paypal_bilan \
--bnc --debug --usdeur 1.2981 "$f" \
> "$f2"
echo diff "$f1" "$f2"
diff "$f1" "$f2"
done
for f in /g/paypal/paypal_201?_??.csv; do
fb=`basename "$f" .csv`
#echo $fb
f1i=/g/paypal/$fb.csv
f2i=/g/paypal/${fb}_complet.csv
f1o=/g/var/paypal_bilan/tests/t03_$fb.out1
f2o=/g/var/paypal_bilan/tests/t03_$fb.out2
#echo $f1i
#echo $f2i
#echo $f1o
#echo $f2o
rm -f "$f1o" "$f2o"
/g/public_html/imapsync/paypal_reply/paypal_bilan \
--bnc --debug "$f1i" \
> "$f1o"
/g/public_html/imapsync/paypal_reply/paypal_bilan \
--bnc --debug "$f2i" \
> "$f2o"
echo diff "$f1o" "$f2o"
diff "$f1o" "$f2o"
done
)
}
#echo paypal_bilan_tests_dev
paypal_bilan_tests_dev() {
/g/public_html/imapsync/paypal_reply/paypal_bilan \
/g/paypal/paypal_201?_??_complet.csv --invoices '1 50 200'
# Strange characters
/g/public_html/imapsync/paypal_reply/paypal_bilan \
/g/paypal/paypal_201?_??_complet.csv --invoices '389 234 96'
# France
/g/public_html/imapsync/paypal_reply/paypal_bilan \
/g/paypal/paypal_201?_??_complet.csv --invoices '9 392'
# individual
/g/public_html/imapsync/paypal_reply/paypal_bilan \
/g/paypal/paypal_201?_??_complet.csv --invoices '313 415'
# /g/public_html/imapsync/paypal_reply/paypal_bilan /g/paypal/paypal_2011_03_complet.csv
# pb with latex
# Ok 10 # character
# 65 clientAdrB Keyboard character used is undefined YOSHITO YONEI
# Ok 84 Missing $ inserted. clientEmail victor_su@yahoo.com
# 92 Dr. Westernacher & Partner GmbH
# /g/public_html/imapsync/paypal_reply/paypal_bilan --first_in 147 --invoices '242' /g/paypal/paypal_2010_1?_complet.csv
}

View File

@ -1,773 +0,0 @@
#!/usr/bin/perl
# $Id: paypal_bilan,v 1.23 2011/04/19 14:59:43 gilles Exp gilles $
use strict;
use warnings;
use Getopt::Long;
use Text::CSV_XS ;
use IO::Handle ;
use Data::Dumper ;
use Unicode::MapUTF8 qw(to_utf8 from_utf8 utf8_supported_charset);
die unless (utf8_supported_charset('ISO-8859-1'));
my $total_usd_received = 0 ;
my $total_usd_invoice = 0 ;
my $total_HT_EUR_exo = 0 ;
my $total_HT_EUR_ass = 0 ;
my $total_TVA_EUR = 0 ;
my $total_eur_received = 0 ;
my $total_eur_invoice = 0 ;
my $nb_invoice = 0 ;
my $nb_invoice_refund = 0 ;
my $debug ;
my $debug_csv ;
my $debug_dev ;
my $first_invoice = 1 ;
my $print_details = '' ;
my $bnc = '';
my $usdeur = 1.2981 ;
my $invoices ;
my %invoice_refund ;
my $write_invoices = 0;
my $dir_invoices = '/g/var/paypal_invoices' ;
my $option_ret = GetOptions (
'debug' => \$debug,
'debug_csv' => \$debug_csv,
'debug_dev' => \$debug_dev,
'first_invoice=i' => \$first_invoice,
'print_details|details' => \$print_details,
'bnc' => \$bnc,
'usdeur=f' => \$usdeur,
'invoices=s' => \$invoices,
'write_invoices!' => \$write_invoices,
);
my @files = @ARGV ;
my %action_of_invoice ;
my @invoices = split( /\s+/, $invoices ) if $invoices ;
#print "@invoices\n" ;
foreach my $file ( @files ) {
my @actions = parse_file( $file ) ;
foreach my $action (@actions) {
my %action = %$action ;
#print $action->{ Nom }, "\n" ;
my( $Date, $Heure, $Fuseau_horaire, $Nom, $Type, $Etat,
$Devise, $Montant, $Numero_davis_de_reception, $Solde,
$Pays, $Nom_Option_1, $Valeur_Option_1, $Hors_taxe )
= @action{ ( 'Date', 'Heure', 'Fuseau horaire', 'Nom', 'Type', 'Etat',
'Devise', 'Montant', "Numéro d'avis de réception", 'Solde',
'Pays', 'Nom Option 1', 'Valeur Option 1', 'Hors taxe') } ;
#print "$Nom\n" ;
my $invoice = 'NONE' ;
$Montant = $action->{ Net } if not defined $Montant;
compute_line($action, $invoice, $Date, $Heure, $Fuseau_horaire, $Nom, $Type, $Etat,
$Devise, $Montant, $Numero_davis_de_reception, $Solde,
$Pays, $Nom_Option_1, $Valeur_Option_1, $Hors_taxe ) ;
# index by invoice number
$action_of_invoice{ $action->{ 'invoice' } } = $action ;
}
delete $action_of_invoice{ 'NONE' } ;
}
@invoices = ( $first_invoice .. $first_invoice + $nb_invoice -1 ) if ( ! @invoices ) ;
foreach my $invoice ( @invoices ) {
build_invoice( $invoice ) ;
}
print "USD banque $total_usd_received\n" ;
print "USD invoice $total_usd_invoice\n" ;
my $total_eur_from_usd ;
$total_eur_from_usd = int( ( $total_usd_invoice / $usdeur ) + 0.5 ) ; # au 30 nov 2010 http://fr.finance.yahoo.com/devises/convertisseur/#from=EUR;to=USD;amt=1
print "EUR from USD $total_eur_from_usd\n" ;
#$total_eur = int( ( $total_eur_invoice / 1.3 ) + 0.5 ) ;
#print "EUR $total_eur_from_usd\n" ;
print "EUR banque $total_eur_received\n" ;
print "EUR invoice $total_eur_invoice\n" ;
my $total_eur = $total_eur_from_usd + $total_eur_invoice ;
$total_HT_EUR_exo = sprintf('%2.f', $total_HT_EUR_exo) ;
$total_HT_EUR_ass = sprintf('%2.f', $total_HT_EUR_ass) ;
$total_TVA_EUR = sprintf('%2.f', $total_TVA_EUR) ;
$total_eur = sprintf('%2.f', $total_eur) ;
print "EUR total $total_eur\n" ;
print "EUR total HT exo $total_HT_EUR_exo\n" ;
print "EUR total HT assuj $total_HT_EUR_ass\n" ;
print "EUR total TVA $total_TVA_EUR\n" ;
print "Nb invoice $nb_invoice\n" ;
print "Nb invoice refund $nb_invoice_refund\n" ;
print "$total_eur != $total_HT_EUR_exo + $total_HT_EUR_ass + $total_TVA_EUR\n"
if ( $total_eur != $total_HT_EUR_exo + $total_HT_EUR_ass + $total_TVA_EUR ) ;
sub parse_one_line_io {
my $csv = shift ;
my $io = shift ;
my $line = $csv->getline($io) ;
return if ( $csv->eof( ) ) ;
if ( not defined( $line ) ) {
my($cde, $str, $pos) = $csv->error_diag () ;
print "[$cde] [$str] [$pos]\n" ;
}
return( $line ) ;
}
sub hash_and_count_dupplicate {
my @columns = @_ ;
my %columns ;
#@columns_def{ @columns_def } = ( ) ;
foreach my $col ( @columns ) {
$columns{ $col } += 1 ;
}
$debug_csv and print "Nb columns: ", scalar( keys %columns ), " ", scalar( @columns ), "\n" ;
# debug how many time a title is defined
foreach my $col (1 .. scalar( @columns )) {
$debug_csv and print "$col | ",
deci_to_AA( $col ) , " | ",
$columns{ $columns[ $col - 1 ] }, " | ",
$columns[ $col - 1 ], "\n" ;
}
# exit in case two columns have the same name
die "Erreur : doublons dans les titres\n" if ( scalar( keys %columns ) != scalar( @columns ) ) ;
return( %columns ) ;
}
sub deci_to_AA {
my $deci = shift ;
my $AA = '';
while ( $deci > 0 ) {
my $quot = int( ( $deci - 1 ) / 26 ) ;
my $rest = $deci - 1 - ( 26 * $quot ) ;
my $char = chr ( ord('A') + $rest ) ;
$AA = $char . $AA ;
$deci = $quot ;
}
#print "col=$AA\n" ;
return( $AA ) ;
}
sub remove_first_blank {
my $string = shift ;
$string =~ s/^ +// ;
return( $string ) ;
}
sub parse_file {
my $file = shift ;
open my $io, "<", $file or die "$file: $!" ;
my $csv = Text::CSV_XS->new( {
sep_char => ',',
binary => 1,
keep_meta_info => 1,
eol => $/,
} ) ;
my $line_1 = parse_one_line_io( $csv, $io ) ;
die if ( not defined $line_1 ) ; # first line must have no problem
my @columns_def_orig = @$line_1 ;
my @columns_def = map { remove_first_blank( $_ ) } @columns_def_orig ;
$debug_csv and print "columns_def = ", map( { "[$_]" } @columns_def ), "\n";
my %columns_def = hash_and_count_dupplicate( @columns_def ) ;
my $nb_columns_def = scalar @columns_def ;
my $line_counter = 2 ;
my @actions ;
while ( 1 ) {
$debug_csv and print "ligne $line_counter ", $csv->eof( ), "\n" ;
my $line = parse_one_line_io( $csv, $io ) ;
last if ( $csv->eof( ) ) ;
if ( not defined $line ) {
print "Erreur ligne $line_counter : ", $csv->error_diag, "\n\n";
++$line_counter ;
next ;
}
my @columns = @$line ;
if ( $nb_columns_def != scalar @columns ) {
print "Erreur ligne $line_counter : nombre de colonnes = ", scalar @columns, " != $nb_columns_def\n" ;
++$line_counter ;
next ;
}
my %columns ;
@columns{ @columns_def } = @columns ;
$columns{ 'file_csv' } = $file ;
$columns{ 'line_number' } = $line_counter ;
$csv->combine( @columns ) ;
my $line_csv = $csv->string();
$columns{ 'line_csv' } = $line_csv ;
$debug_csv and print map( { "[$_] = [" . $columns{$_} . "]\n" }
@columns_def, 'line_number', 'line_csv', 'file_csv' ),
"\n";
++$line_counter ;
push( @actions, \%columns ) ;
}
close( $io );
return( reverse @actions ) ;
}
sub compute_line {
my( $action, $invoice, $Date, $Heure, $Fuseau_horaire, $Nom, $Type, $Etat,
$Devise, $Montant, $Numero_davis_de_reception, $Solde,
$Pays, $Nom_Option_1, $Valeur_Option_1, $Hors_taxe_paypal ) = @_ ;
$debug and print( "[$Date] [$Heure] [$Fuseau_horaire] [$Nom] [$Type] [$Etat] [$Devise] [$Montant] [$Numero_davis_de_reception] [$Solde]\n",
"[$Pays] [$Nom_Option_1] [$Valeur_Option_1]\n" ) ;
#$debug_dev and print "$Hors_taxe_paypal\n" ;
$Montant =~ s/[^0-9-,.]//g ;
$Montant =~ s/,/./g ;
#$debug and print "MM[$Montant]\n" ;
$Hors_taxe_paypal =~ s/,/./g ;
my $MontantEUR;
my( $montant_HT_EUR_exo, $montant_HT_EUR_ass, $montant_TVA_EUR ) ;
if ( $bnc ) {
$MontantEUR = $Montant ;
$MontantEUR = sprintf( "%.4f", $Montant/$usdeur ) if ($Devise eq 'USD') ;
print( "\n", "=" x 60, "\n" ) ;
print( "[$Date] [$Nom] [$Type] [$Etat] [$Devise] [$Montant] [EUR $MontantEUR]\n",
"[$Pays] [$Nom_Option_1] [$Valeur_Option_1]\n" ) ;
}
if (
'Paiement sur site marchand reçu' eq $Type
and 'USD' eq $Devise
and ( 'Terminé' eq $Etat or 'Compensé' eq $Etat )
) {
$Montant =~tr/,/./;
#print "$Montant\n" ;
my $Montant2_usd;
$Montant2_usd = $Hors_taxe_paypal ;
$total_usd_received += $Montant ;
$total_usd_invoice += $Montant2_usd ;
( $montant_HT_EUR_exo, $montant_HT_EUR_ass, $montant_TVA_EUR ) = tva_line( $Devise, $Montant2_usd, $Pays, $Nom_Option_1, $Valeur_Option_1 ) ;
$total_HT_EUR_exo += $montant_HT_EUR_exo ;
$total_HT_EUR_ass += $montant_HT_EUR_ass ;
$total_TVA_EUR += $montant_TVA_EUR ;
$invoice = $first_invoice + $nb_invoice ;
$nb_invoice++ ;
$print_details and print ( "[$invoice] [$Date] [$Heure] [$Fuseau_horaire] [$Nom] [$Type] [$Etat] [$Devise] [$Montant] [$Numero_davis_de_reception] [$Solde]\n" ) ;
}
if (
'Paiement sur site marchand reçu' eq $Type
and 'EUR' eq $Devise
and ( 'Terminé' eq $Etat or 'Compensé' eq $Etat )
) {
$Montant =~tr/,/./;
#print "$Montant\n" ;
my $Montant2_eur;
$Montant2_eur = $Hors_taxe_paypal ;
$total_eur_received += $Montant ;
$total_eur_invoice += $Montant2_eur ;
( $montant_HT_EUR_exo, $montant_HT_EUR_ass, $montant_TVA_EUR ) = tva_line( $Devise, $Montant2_eur, $Pays, $Nom_Option_1, $Valeur_Option_1 ) ;
$total_HT_EUR_exo += $montant_HT_EUR_exo ;
$total_HT_EUR_ass += $montant_HT_EUR_ass ;
$total_TVA_EUR += $montant_TVA_EUR ;
$invoice = $first_invoice + $nb_invoice ;
$nb_invoice++ ;
$print_details and print ( "[$invoice] [$Date] [$Heure] [$Fuseau_horaire] [$Nom] [$Type] [$Etat] [$Devise] [$Montant] [$Numero_davis_de_reception] [$Solde]\n" ) ;
}
if (
'Paiement sur site marchand reçu' eq $Type
and 'EUR' eq $Devise
and 'Remboursé' eq $Etat
) {
$invoice = $first_invoice + $nb_invoice ;
$nb_invoice++ ;
$nb_invoice_refund++;
$invoice_refund{ $invoice }++ ;
$print_details and print ( "[$invoice] [$Date] [$Heure] [$Fuseau_horaire] [$Nom] [$Type] [$Etat] [$Devise] [$Montant] [$Numero_davis_de_reception] [$Solde]\n" ) ;
}
if (
'Paiement sur site marchand reçu' eq $Type
and 'EUR' eq $Devise
and 'Non compensé' eq $Etat
) {
$invoice = $first_invoice + $nb_invoice ;
$nb_invoice++ ;
$print_details and print ( "[$invoice] [$Date] [$Heure] [$Fuseau_horaire] [$Nom] [$Type] [$Etat] [$Devise] [$Montant] [$Numero_davis_de_reception] [$Solde]\n" ) ;
}
$action->{ 'invoice' } = $invoice ;
if ( $bnc ) {
my $FR_flag = '' ;
$FR_flag = ' FR' if $Pays eq 'France' ;
my $IND_flag = '' ;
$IND_flag = ' IND' if ('imapsync usage' eq $Nom_Option_1 and 'individual' eq $Valeur_Option_1 ) ;
print "FE $invoice$FR_flag$IND_flag\n" ;
print "Facture $invoice imapsync$FR_flag $Nom\n" ;
printf( "%.2f [EUR %.2f]\n", $Montant, $MontantEUR ) ;
}
}
sub build_invoice {
my $invoice = shift ;
return if ! $invoice ;
my $action = $action_of_invoice{ $invoice } ;
my $refund = '' ;
$refund = 'REFUND ' if $invoice_refund{ $invoice } ;
my %action = %$action if $action ;
#print Data::Dumper->Dump( [$action] ) ;
my( $Date, $Heure, $Nom, $Type, $Etat, $Devise, $Hors_taxe, $Commission, $Net,
$De_l_adresse_email, $A_l_adresse_email, $N_de_transaction, $Titre_de_l_objet,
$TVA, $Nom_Option_1, $Valeur_Option_1, $N_de_transaction_de_reference,
$Adresse_1, $Adresse_2_district_quartier, $Ville,
$Etat_Province, $Code_postal, $Pays, $line_number, $line_csv, $file_csv )
= @action{ ( 'Date', 'Heure', 'Nom', 'Type', 'Etat', 'Devise', 'Hors taxe', 'Commission', 'Net',
"De l'adresse email", "A l'adresse email", 'N° de transaction', "Titre de l'objet",
'TVA', 'Nom Option 1', 'Valeur Option 1', 'Nº de transaction de référence',
'Adresse 1', 'Adresse 2/district/quartier', 'Ville',
'Etat/Province/Région/Comté/Territoire/Préfecture/République', 'Code postal', 'Pays', 'line_number', 'line_csv', 'file_csv' ) } ;
#print "$Hors_taxe $Devise\n" ;
my $Hors_taxe_num = $Hors_taxe ;
$Hors_taxe_num =~ s{,}{.} ;
if ($Hors_taxe_num > 100) {
print "invoice $invoice $Hors_taxe_num > 100\n" ;
#return() ;
}
my ( $email_message_header, $email_message_body )
= build_email_message( $Date, $Nom, $De_l_adresse_email, $invoice ) ;
if ( $write_invoices ) {
write_email_message( $dir_invoices, $invoice,
$email_message_header, $email_message_body,
$De_l_adresse_email) ;
write_csv_info( $dir_invoices, $invoice, $file_csv, $line_number, $line_csv ) ;
}
#print "==== $invoice $refund=================================================" ;
#print $email_message ;
my(
$clientAdrA,
$clientAdrB,
$clientAdrC,
$clientAdrD,
$clientAdrE,
$clientAdrF,
)
= build_adress(
$Nom,
$Adresse_1,
$Adresse_2_district_quartier,
$Ville,
$Code_postal,
$Etat_Province,
$Pays,
) ;
foreach my $str (
$De_l_adresse_email,
$Nom,
$clientAdrA,
$clientAdrB,
$clientAdrC,
$clientAdrD,
$clientAdrE,
$clientAdrF,
) {
$str =~ s{#}{\\#}g ;
$str =~ s{_}{\\_}g ;
$str =~ s{&}{\\&}g ;
}
my ( $clientTypeEN, $clientTypeFR ) = client_type( $Nom_Option_1, $Valeur_Option_1 ) ;
my (
$priceHT,
$tvaFR,
$tvaEN,
$priceTVA,
$priceTTC,
$messageTVAFR,
$messageTVAEN,
$priceTTCusd
)
= tva_stuff( $clientTypeEN, $Pays, $Hors_taxe, $Devise ) ;
my ( $urlSrc, $urlExe ) = download_urls( $Date ) ;
my $tex_variables = qq{
%% Begin input from $0
\\providecommand{\\invoiceNumber}{$invoice}
\\providecommand{\\clientName}{$Nom}
\\providecommand{\\clientEmail}{$De_l_adresse_email}
\\providecommand{\\clientTypeEN}{$clientTypeEN}
\\providecommand{\\clientTypeFR}{$clientTypeFR}
\\providecommand{\\clientAdrA}{$clientAdrA}
\\providecommand{\\clientAdrB}{$clientAdrB}
\\providecommand{\\clientAdrC}{$clientAdrC}
\\providecommand{\\clientAdrD}{$clientAdrD}
\\providecommand{\\clientAdrE}{$clientAdrE}
\\providecommand{\\clientAdrF}{$clientAdrF}
\\providecommand{\\invoiceDate}{$Date}
\\providecommand{\\invoiceHour}{$Heure}
\\providecommand{\\priceHT}{$priceHT}
\\providecommand{\\tvaFR}{$tvaFR}
\\providecommand{\\tvaEN}{$tvaEN}
\\providecommand{\\priceTVA}{$priceTVA}
\\providecommand{\\priceTTC}{$priceTTC}
\\providecommand{\\priceTTCusd}{$priceTTCusd}
\\providecommand{\\messageTVAFR}{$messageTVAFR}
\\providecommand{\\messageTVAEN}{$messageTVAEN}
\\providecommand{\\urlSrc}{\\url{$urlSrc}}
\\providecommand{\\urlExe}{\\url{$urlExe}}
%% End input from $0
} ;
#print $tex_variables ;
write_tex_variables_file( $dir_invoices,
$invoice, $Date, $tex_variables ) if $write_invoices ;
}
sub build_email_message {
my ( $date, $name, $email, $invoice ) = @_ ;
my $message_header = qq{X-imapsync: invoice $invoice
From: Gilles LAMIRAL <gilles.lamiral\@laposte.net>
Bcc: gilles\@lamiral.info
Subject: [imapsync invoice] $invoice ($date)
Disposition-Notification-To: Gilles LAMIRAL <gilles.lamiral\@laposte.net>
} ;
my $message_body = qq{
Hello $name,
First I'm sorry for the delay to prepare and send you this message.
Attached is the invoice of imapsync software you bought ($date).
The invoice file is named facture_imapsync-${invoice}.pdf
This invoice is in PDF format, ready to be print.
If you need this invoice on paper, just ask me then
I will send it to you by postal mail.
In order to respect the law, this numeric invoice PDF
file is signed with my private gpg key.
The resulting gpg signature is in the file named
facture_imapsync-${invoice}.pdf.asc
also attached in this email message.
You can verify I (Gilles LAMIRAL) really generated
this invoice with the following command line
gpg --verify facture_imapsync-${invoice}.pdf.asc facture_imapsync-${invoice}.pdf
or any other gpg graphical tool.
I thank you again for buying and using imapsync.
Any feedback is welcome.
--
Au revoir, 09 51 84 42 42
Gilles Lamiral. France, Baulon (35580) 06 20 79 76 06
} ;
my $message_body_blabla = qq{
Here is the fingerprint of my public key
pub 1024D/FDA2B3DC 2002-05-08
Key fingerprint = 7906 F53D 0D62 0C67 304A 4CF0 6928 869B FDA2 B3DC
uid Gilles LAMIRAL <gilles.lamiral\@laposte.net>
sub 1024g/A2C4CB42 2002-05-08
Of course the verification doesn't prove anything until
all the following conditions are met:
- you met me,
- I agree that the fingerprint above is really mine
- I prove I'm Gilles LAMIRAL with an official paper.
Normally we won't have to verify anything unless
I disagree with this invoice and the payment
you made for imapsync.
} ;
return( $message_header, $message_body ) ;
}
sub write_csv_info {
my( $dir_invoices, $invoice, $file_csv, $line_number, $line_csv ) = @_ ;
open( CSVINFO, "> $dir_invoices/$invoice/csv_info.txt") or die ;
print CSVINFO join( "\n", $file_csv, $line_number, $line_csv ) ;
close( CSVINFO ) ;
}
sub write_email_message {
my ( $dir_invoices, $invoice, $message_header, $message_body, $email_address ) = @_ ;
my $message_body_utf8 = to_utf8({ -string => $message_body, -charset => 'ISO-8859-1' });
mkdir( "$dir_invoices/$invoice" ) or die if ! -d "$dir_invoices/$invoice" ;
open( HEADER, "> $dir_invoices/$invoice/facture_message_header.txt") or die ;
print HEADER $message_header ;
close( HEADER ) ;
open( BODY, "> $dir_invoices/$invoice/facture_message_body.txt") or die ;
print BODY $message_body_utf8 ;
close( BODY ) ;
open( ADDRESS, "> $dir_invoices/$invoice/email_address.txt") or die ;
print ADDRESS "$email_address\n" ;
close( ADDRESS ) ;
}
sub write_tex_variables_file {
my ( $dir_invoices, $invoice, $date_jjSmmSaaaa, $tex_variables ) = @_ ;
my $tex_variables_utf8 = to_utf8({ -string => $tex_variables, -charset => 'ISO-8859-1' });
mkdir( "$dir_invoices/$invoice" ) or die if ! -d "$dir_invoices/$invoice" ;
open( FILE, "> $dir_invoices/$invoice/imapsync_var.tex") or die ;
print FILE $tex_variables_utf8 ;
close( FILE ) ;
}
sub download_urls {
my $date_jjSmmSaaaa = shift ;
my $date_aaaa_mm_jj = date_aaaa_mm_jj( $date_jjSmmSaaaa ) ;
# print "$date_aaaa_mm_jj $date_jjSmmSaaaa\n" ;
my ( $urlSrc, $urlExe ) ;
if ('2011_03_24' le $date_aaaa_mm_jj) {
$urlSrc = 'http://www.linux-france.org/prj/imapsync/paypal_return.shtml' ;
$urlExe = '' ;
return( $urlSrc, $urlExe ) ;
}
if ('2011_02_21' le $date_aaaa_mm_jj) {
$urlSrc = 'http://www.linux-france.org/depot/2011_02_21/OUMbo7/' ;
$urlExe = 'http://www.linux-france.org/depot/2011_02_21/rHSVNs/' ;
return( $urlSrc, $urlExe ) ;
}
if ('2011_01_18' le $date_aaaa_mm_jj) {
$urlSrc = 'http://www.linux-france.org/depot/2011_01_18/zPRRNt/' ;
$urlExe = 'http://www.linux-france.org/depot/2011_01_18/FO1QzG/' ;
return( $urlSrc, $urlExe ) ;
}
if ('2011_01_18' le $date_aaaa_mm_jj) {
$urlSrc = 'http://www.linux-france.org/depot/2010_11_28/SiNdlZ/' ;
$urlExe = 'http://www.linux-france.org/depot/2010_11_28/R3ZAyr/' ;
return( $urlSrc, $urlExe ) ;
}
$urlSrc = 'http://www.linux-france.org/depot/2010_11_08/X2PWMe/' ;
$urlExe = 'http://www.linux-france.org/depot/2010_11_08/ZZ7zSc/' ;
return( $urlSrc, $urlExe ) ;
}
sub date_aaaa_mm_jj {
my $date_jjSmmSaaaa = shift ;
if ( $date_jjSmmSaaaa =~ m{(\d\d)/(\d\d)/(\d\d\d\d)} ) {
my( $jj, $mm, $aaaa ) = ( $1, $2, $3 ) ;
return( join( '_', $aaaa, $mm, $jj ) ) ;
}else{
return( '9999_12_31' ) ;
}
}
sub tva_line {
my( $Devise, $Montant2, $Pays, $Nom_Option_1, $Valeur_Option_1 ) = @_ ;
my( $montant_HT_EUR_exo, $montant_HT_EUR_ass, $montant_TVA_EUR ) ;
$Montant2 = $Montant2/$usdeur if 'USD' eq $Devise ;
if (
( 'imapsync usage' eq $Nom_Option_1 and 'individual' eq $Valeur_Option_1 )
or
( 'France' eq $Pays )
) {
$montant_HT_EUR_exo = 0 ;
$montant_HT_EUR_ass = $Montant2 / 1.196 ;
$montant_TVA_EUR = $Montant2 / 1.196 * 0.196 ;
$debug_dev and print "$Montant2 $Pays $Valeur_Option_1\n" ;
}else{
$montant_HT_EUR_exo = $Montant2 ;
$montant_HT_EUR_ass = 0 ;
$montant_TVA_EUR = 0 ;
}
return( $montant_HT_EUR_exo, $montant_HT_EUR_ass, $montant_TVA_EUR ) ;
}
sub tva_stuff {
my( $clientTypeEN, $Pays, $Hors_taxe, $Devise ) = @_ ;
my $priceTTCusd = '' ;
$Hors_taxe =~ s{,}{.} ;
if ( $Devise eq 'USD' ) {
$priceTTCusd = "(USD $Hors_taxe)" ;
$Hors_taxe = ( $Hors_taxe/$usdeur ) ;
}
my (
$priceHT,
$tvaFR,
$tvaEN,
$priceTVA,
$priceTTC,
$messageTVAFR,
$messageTVAEN,
) ;
if ( ( 'individual' eq $clientTypeEN)
or
( 'France' eq $Pays )
) {
$priceHT = sprintf('%2.2f', $Hors_taxe/1.196) ;
$tvaFR = '19,60\%';
$tvaEN = '';
$priceTVA = sprintf('%2.2f', $Hors_taxe/1.196*0.196) ;
$priceTTC = sprintf('%2.2f', $Hors_taxe) ;
$messageTVAFR = '';
$messageTVAEN = '';
}else{
$priceHT = sprintf('%2.2f', $Hors_taxe) ;
$tvaFR = 'néant';
$tvaEN = '(none)';
$priceTVA = 0 ;
$priceTTC = $priceHT;
$messageTVAFR = 'Exonération de TVA, article 259 B-1 du Code Général des Impôts';
$messageTVAEN = '(VAT tax-exempt, article 259 B-1 French General Tax Code)';
}
foreach my $price ( $priceHT, $priceTVA, $priceTTC, $priceTTCusd ) {
#print "[$price]\n" ;
$price =~ s{\.}{, } ;
}
return(
$priceHT,
$tvaFR,
$tvaEN,
$priceTVA,
$priceTTC,
$messageTVAFR,
$messageTVAEN,
$priceTTCusd
) ;
}
sub client_type {
my ( $Nom_Option_1, $Valeur_Option_1 ) = @_ ;
my ( $clientTypeEN, $clientTypeFR ) = ( 'professional', 'professionnel' ) ;
if ('imapsync usage' eq $Nom_Option_1 and 'individual' eq $Valeur_Option_1 ) {
$clientTypeEN = 'individual' ;
$clientTypeFR = 'individuel' ;
}elsif ('imapsync usage' eq $Nom_Option_1 and 'professional' eq $Valeur_Option_1 ) {
$clientTypeEN = 'professional' ;
$clientTypeFR = 'professionnel' ;
}
return( $clientTypeEN, $clientTypeFR ) ;
}
sub build_adress {
my(
$Nom,
$Adresse_1,
$Adresse_2_district_quartier,
$Ville,
$Code_postal,
$Etat_Province,
$Pays,
) = @_ ;
my $addr = "
===========================================================
Nom $Nom
Adresse_1 $Adresse_1
Adresse_2_district_quartier $Adresse_2_district_quartier
Ville Code_postal $Ville $Code_postal
Etat_Province $Etat_Province
Pays $Pays
" ;
#print $addr ;
my @address ;
$Nom = '' if ( $Nom =~ m/^\s+$/ ) ;
push( @address, $Nom ) if $Nom ;
push( @address, $Adresse_1 ) if $Adresse_1 ;
push( @address, $Adresse_2_district_quartier ) if $Adresse_2_district_quartier ;
push( @address, "$Ville $Code_postal" ) if ( $Ville or $Code_postal );
push( @address, $Etat_Province ) if $Etat_Province ;
push( @address, $Pays, ) if $Pays ;
my $clientAdrA = shift( @address ) || '' ;
my $clientAdrB = shift( @address ) || '' ;
my $clientAdrC = shift( @address ) || '' ;
my $clientAdrD = shift( @address ) || '' ;
my $clientAdrE = shift( @address ) || '' ;
my $clientAdrF = shift( @address ) || '' ;
$addr = "
[$clientAdrA]
[$clientAdrB]
[$clientAdrC]
[$clientAdrD]
[$clientAdrE]
[$clientAdrF]
";
#print $addr ;
return(
$clientAdrA,
$clientAdrB,
$clientAdrC,
$clientAdrD,
$clientAdrE,
$clientAdrF,
) ;
}

View File

@ -1,756 +0,0 @@
#!/usr/bin/perl
# $Id: paypal_bilan,v 1.22 2011/04/19 12:52:27 gilles Exp gilles $
use strict;
use warnings;
use Getopt::Long;
use Text::CSV_XS ;
use IO::Handle ;
use Data::Dumper ;
use Unicode::MapUTF8 qw(to_utf8 from_utf8 utf8_supported_charset);
die unless (utf8_supported_charset('ISO-8859-1'));
my $total_usd_received = 0 ;
my $total_usd_invoice = 0 ;
my $total_eur_received = 0 ;
my $total_eur_invoice = 0 ;
my $nb_invoice = 0 ;
my $nb_invoice_refund = 0 ;
my $debug ;
my $debug_csv ;
my $debug_dev ;
my $first_invoice = 1 ;
my $print_details = '' ;
my $bnc = '';
my $usdeur = 1.2981 ;
my $invoices ;
my %invoice_refund ;
my $write_invoices = 0;
my $dir_invoices = '/g/var/paypal_invoices' ;
my $option_ret = GetOptions (
'debug' => \$debug,
'debug_csv' => \$debug_csv,
'debug_dev' => \$debug_dev,
'first_invoice=i' => \$first_invoice,
'print_details|details' => \$print_details,
'bnc' => \$bnc,
'usdeur=f' => \$usdeur,
'invoices=s' => \$invoices,
'write_invoices!' => \$write_invoices,
);
my @files = @ARGV ;
my %action_of_invoice ;
my @invoices = split( /\s+/, $invoices ) if $invoices ;
#print "@invoices\n" ;
foreach my $file ( @files ) {
my @actions = parse_file( $file ) ;
foreach my $action (@actions) {
my %action = %$action ;
#print $action->{ Nom }, "\n" ;
my( $Date, $Heure, $Fuseau_horaire, $Nom, $Type, $Etat,
$Devise, $Montant, $Numero_davis_de_reception, $Solde,
$Pays, $Nom_Option_1, $Valeur_Option_1, $Hors_taxe )
= @action{ ( 'Date', 'Heure', 'Fuseau horaire', 'Nom', 'Type', 'Etat',
'Devise', 'Montant', "Numéro d'avis de réception", 'Solde',
'Pays', 'Nom Option 1', 'Valeur Option 1', 'Hors taxe') } ;
#print "$Nom\n" ;
my $invoice = 'NONE' ;
$Montant = $action->{ Net } if not defined $Montant;
compute_line($action, $invoice, $Date, $Heure, $Fuseau_horaire, $Nom, $Type, $Etat,
$Devise, $Montant, $Numero_davis_de_reception, $Solde,
$Pays, $Nom_Option_1, $Valeur_Option_1, $Hors_taxe ) ;
# index by invoice number
$action_of_invoice{ $action->{ 'invoice' } } = $action ;
}
delete $action_of_invoice{ 'NONE' } ;
}
@invoices = ( $first_invoice .. $first_invoice + $nb_invoice -1 ) if ( ! @invoices ) ;
foreach my $invoice ( @invoices ) {
build_invoice( $invoice ) ;
}
print "USD banque $total_usd_received\n" ;
print "USD invoice $total_usd_invoice\n" ;
my $total_eur_from_usd ;
$total_eur_from_usd = int( ( $total_usd_invoice / $usdeur ) + 0.5 ) ; # au 30 nov 2010 http://fr.finance.yahoo.com/devises/convertisseur/#from=EUR;to=USD;amt=1
print "EUR from USD $total_eur_from_usd\n" ;
#$total_eur = int( ( $total_eur_invoice / 1.3 ) + 0.5 ) ;
#print "EUR $total_eur_from_usd\n" ;
print "EUR banque $total_eur_received\n" ;
print "EUR invoice $total_eur_invoice\n" ;
my $total_eur = $total_eur_from_usd + $total_eur_invoice ;
print "EUR total $total_eur\n" ;
print "Nb invoice $nb_invoice\n" ;
print "Nb invoice refund $nb_invoice_refund\n" ;
sub parse_one_line_io {
my $csv = shift ;
my $io = shift ;
my $line = $csv->getline($io) ;
return if ( $csv->eof( ) ) ;
if ( not defined( $line ) ) {
my($cde, $str, $pos) = $csv->error_diag () ;
print "[$cde] [$str] [$pos]\n" ;
}
return( $line ) ;
}
sub hash_and_count_dupplicate {
my @columns = @_ ;
my %columns ;
#@columns_def{ @columns_def } = ( ) ;
foreach my $col ( @columns ) {
$columns{ $col } += 1 ;
}
$debug_csv and print "Nb columns: ", scalar( keys %columns ), " ", scalar( @columns ), "\n" ;
# debug how many time a title is defined
foreach my $col (1 .. scalar( @columns )) {
$debug_csv and print "$col | ",
deci_to_AA( $col ) , " | ",
$columns{ $columns[ $col - 1 ] }, " | ",
$columns[ $col - 1 ], "\n" ;
}
# exit in case two columns have the same name
die "Erreur : doublons dans les titres\n" if ( scalar( keys %columns ) != scalar( @columns ) ) ;
return( %columns ) ;
}
sub deci_to_AA {
my $deci = shift ;
my $AA = '';
while ( $deci > 0 ) {
my $quot = int( ( $deci - 1 ) / 26 ) ;
my $rest = $deci - 1 - ( 26 * $quot ) ;
my $char = chr ( ord('A') + $rest ) ;
$AA = $char . $AA ;
$deci = $quot ;
}
#print "col=$AA\n" ;
return( $AA ) ;
}
sub remove_first_blank {
my $string = shift ;
$string =~ s/^ +// ;
return( $string ) ;
}
sub parse_file {
my $file = shift ;
open my $io, "<", $file or die "$file: $!" ;
my $csv = Text::CSV_XS->new( {
sep_char => ',',
binary => 1,
keep_meta_info => 1,
eol => $/,
} ) ;
my $line_1 = parse_one_line_io( $csv, $io ) ;
die if ( not defined $line_1 ) ; # first line must have no problem
my @columns_def_orig = @$line_1 ;
my @columns_def = map { remove_first_blank( $_ ) } @columns_def_orig ;
$debug_csv and print "columns_def = ", map( { "[$_]" } @columns_def ), "\n";
my %columns_def = hash_and_count_dupplicate( @columns_def ) ;
my $nb_columns_def = scalar @columns_def ;
my $line_counter = 2 ;
my @actions ;
while ( 1 ) {
$debug_csv and print "ligne $line_counter ", $csv->eof( ), "\n" ;
my $line = parse_one_line_io( $csv, $io ) ;
last if ( $csv->eof( ) ) ;
if ( not defined $line ) {
print "Erreur ligne $line_counter : ", $csv->error_diag, "\n\n";
++$line_counter ;
next ;
}
my @columns = @$line ;
if ( $nb_columns_def != scalar @columns ) {
print "Erreur ligne $line_counter : nombre de colonnes = ", scalar @columns, " != $nb_columns_def\n" ;
++$line_counter ;
next ;
}
my %columns ;
@columns{ @columns_def } = @columns ;
$columns{ 'file_csv' } = $file ;
$columns{ 'line_number' } = $line_counter ;
$csv->combine( @columns ) ;
my $line_csv = $csv->string();
$columns{ 'line_csv' } = $line_csv ;
$debug_csv and print map( { "[$_] = [" . $columns{$_} . "]\n" }
@columns_def, 'line_number', 'line_csv', 'file_csv' ),
"\n";
++$line_counter ;
push( @actions, \%columns ) ;
}
close( $io );
return( reverse @actions ) ;
}
sub compute_line {
my( $action, $invoice, $Date, $Heure, $Fuseau_horaire, $Nom, $Type, $Etat,
$Devise, $Montant, $Numero_davis_de_reception, $Solde,
$Pays, $Nom_Option_1, $Valeur_Option_1, $Hors_taxe_paypal ) = @_ ;
$debug and print( "[$Date] [$Heure] [$Fuseau_horaire] [$Nom] [$Type] [$Etat] [$Devise] [$Montant] [$Numero_davis_de_reception] [$Solde]\n",
"[$Pays] [$Nom_Option_1] [$Valeur_Option_1]\n" ) ;
#$debug_dev and print "$Hors_taxe_paypal\n" ;
$Montant =~ s/[^0-9-,.]//g ;
$Montant =~ s/,/./g ;
#$debug and print "MM[$Montant]\n" ;
$Hors_taxe_paypal =~ s/,/./g ;
my $MontantEUR;
if ( $bnc ) {
$MontantEUR = $Montant ;
$MontantEUR = sprintf( "%.4f", $Montant/$usdeur ) if ($Devise eq 'USD') ;
print( "\n", "=" x 60, "\n" ) ;
print( "[$Date] [$Nom] [$Type] [$Etat] [$Devise] [$Montant] [EUR $MontantEUR]\n",
"[$Pays] [$Nom_Option_1] [$Valeur_Option_1]\n" ) ;
}
if (
'Paiement sur site marchand reçu' eq $Type
and 'USD' eq $Devise
and 'Terminé' eq $Etat
) {
$Montant =~tr/,/./;
#print "$Montant\n" ;
my $Montant2_usd;
$Montant2_usd = $Hors_taxe_paypal ;
$total_usd_received += $Montant ;
$total_usd_invoice += $Montant2_usd ;
$invoice = $first_invoice + $nb_invoice ;
$nb_invoice++ ;
$print_details and print ( "[$invoice] [$Date] [$Heure] [$Fuseau_horaire] [$Nom] [$Type] [$Etat] [$Devise] [$Montant] [$Numero_davis_de_reception] [$Solde]\n" ) ;
}
if (
'Paiement sur site marchand reçu' eq $Type
and 'USD' eq $Devise
and 'Compensé' eq $Etat
) {
$Montant =~tr/,/./;
#print "$Montant\n" ;
my $Montant2_usd;
$Montant2_usd = $Hors_taxe_paypal ;
$total_usd_received += $Montant ;
$total_usd_invoice += $Montant2_usd ;
$invoice = $first_invoice + $nb_invoice ;
$nb_invoice++ ;
$print_details and print ( "[$invoice] [$Date] [$Heure] [$Fuseau_horaire] [$Nom] [$Type] [$Etat] [$Devise] [$Montant] [$Numero_davis_de_reception] [$Solde]\n" ) ;
}
if (
'Paiement sur site marchand reçu' eq $Type
and 'EUR' eq $Devise
and 'Terminé' eq $Etat
) {
$Montant =~tr/,/./;
#print "$Montant\n" ;
my $Montant2_eur;
$Montant2_eur = $Hors_taxe_paypal ;
$total_eur_received += $Montant ;
$total_eur_invoice += $Montant2_eur ;
$invoice = $first_invoice + $nb_invoice ;
$nb_invoice++ ;
$print_details and print ( "[$invoice] [$Date] [$Heure] [$Fuseau_horaire] [$Nom] [$Type] [$Etat] [$Devise] [$Montant] [$Numero_davis_de_reception] [$Solde]\n" ) ;
}
if (
'Paiement sur site marchand reçu' eq $Type
and 'EUR' eq $Devise
and 'Remboursé' eq $Etat
) {
$invoice = $first_invoice + $nb_invoice ;
$nb_invoice++ ;
$nb_invoice_refund++;
$invoice_refund{ $invoice }++ ;
$print_details and print ( "[$invoice] [$Date] [$Heure] [$Fuseau_horaire] [$Nom] [$Type] [$Etat] [$Devise] [$Montant] [$Numero_davis_de_reception] [$Solde]\n" ) ;
}
if (
'Paiement sur site marchand reçu' eq $Type
and 'EUR' eq $Devise
and 'Compensé' eq $Etat
) {
$Montant =~tr/,/./;
#print "$Montant\n" ;
my $Montant2_eur;
$Montant2_eur = 21.99 if ( 20.88 == $Montant or 20.99 == $Montant ) ;
$Montant2_eur = 30 if ( 28.58 == $Montant or 28.73 == $Montant ) ;
$Montant2_eur = 110 if ( 105.46 == $Montant ) ;
#print "$Montant $Montant2_eur\n" ;
$total_eur_received += $Montant ;
$total_eur_invoice += $Montant2_eur ;
$invoice = $first_invoice + $nb_invoice ;
$nb_invoice++ ;
$print_details and print ( "[$invoice] [$Date] [$Heure] [$Fuseau_horaire] [$Nom] [$Type] [$Etat] [$Devise] [$Montant] [$Numero_davis_de_reception] [$Solde]\n" ) ;
}
if (
'Paiement sur site marchand reçu' eq $Type
and 'EUR' eq $Devise
and 'Non compensé' eq $Etat
) {
$invoice = $first_invoice + $nb_invoice ;
$nb_invoice++ ;
$print_details and print ( "[$invoice] [$Date] [$Heure] [$Fuseau_horaire] [$Nom] [$Type] [$Etat] [$Devise] [$Montant] [$Numero_davis_de_reception] [$Solde]\n" ) ;
}
$action->{ 'invoice' } = $invoice ;
if ( $bnc ) {
my $FR_flag = '' ;
$FR_flag = ' FR' if $Pays eq 'France' ;
my $IND_flag = '' ;
$IND_flag = ' IND' if ('imapsync usage' eq $Nom_Option_1 and 'individual' eq $Valeur_Option_1 ) ;
print "FE $invoice$FR_flag$IND_flag\n" ;
print "Facture $invoice imapsync$FR_flag $Nom\n" ;
printf( "%.2f [EUR %.2f]\n", $Montant, $MontantEUR ) ;
}
}
sub build_invoice {
my $invoice = shift ;
return if ! $invoice ;
my $action = $action_of_invoice{ $invoice } ;
my $refund = '' ;
$refund = 'REFUND ' if $invoice_refund{ $invoice } ;
my %action = %$action if $action ;
#print Data::Dumper->Dump( [$action] ) ;
my( $Date, $Heure, $Nom, $Type, $Etat, $Devise, $Hors_taxe, $Commission, $Net,
$De_l_adresse_email, $A_l_adresse_email, $N_de_transaction, $Titre_de_l_objet,
$TVA, $Nom_Option_1, $Valeur_Option_1, $N_de_transaction_de_reference,
$Adresse_1, $Adresse_2_district_quartier, $Ville,
$Etat_Province, $Code_postal, $Pays, $line_number, $line_csv, $file_csv )
= @action{ ( 'Date', 'Heure', 'Nom', 'Type', 'Etat', 'Devise', 'Hors taxe', 'Commission', 'Net',
"De l'adresse email", "A l'adresse email", 'N° de transaction', "Titre de l'objet",
'TVA', 'Nom Option 1', 'Valeur Option 1', 'Nº de transaction de référence',
'Adresse 1', 'Adresse 2/district/quartier', 'Ville',
'Etat/Province/Région/Comté/Territoire/Préfecture/République', 'Code postal', 'Pays', 'line_number', 'line_csv', 'file_csv' ) } ;
#print "$Hors_taxe $Devise\n" ;
my $Hors_taxe_num = $Hors_taxe ;
$Hors_taxe_num =~ s{,}{.} ;
if ($Hors_taxe_num > 100) {
print "invoice $invoice $Hors_taxe_num > 100\n" ;
#return() ;
}
my ( $email_message_header, $email_message_body )
= build_email_message( $Date, $Nom, $De_l_adresse_email, $invoice ) ;
if ( $write_invoices ) {
write_email_message( $dir_invoices, $invoice,
$email_message_header, $email_message_body,
$De_l_adresse_email) ;
write_csv_info( $dir_invoices, $invoice, $file_csv, $line_number, $line_csv ) ;
}
#print "==== $invoice $refund=================================================" ;
#print $email_message ;
my(
$clientAdrA,
$clientAdrB,
$clientAdrC,
$clientAdrD,
$clientAdrE,
$clientAdrF,
)
= build_adress(
$Nom,
$Adresse_1,
$Adresse_2_district_quartier,
$Ville,
$Code_postal,
$Etat_Province,
$Pays,
) ;
foreach my $str (
$De_l_adresse_email,
$Nom,
$clientAdrA,
$clientAdrB,
$clientAdrC,
$clientAdrD,
$clientAdrE,
$clientAdrF,
) {
$str =~ s{#}{\\#}g ;
$str =~ s{_}{\\_}g ;
$str =~ s{&}{\\&}g ;
}
my ( $clientTypeEN, $clientTypeFR ) = client_type( $Nom_Option_1, $Valeur_Option_1 ) ;
my (
$priceHT,
$tvaFR,
$tvaEN,
$priceTVA,
$priceTTC,
$messageTVAFR,
$messageTVAEN,
$priceTTCusd
)
= tva_stuff( $clientTypeEN, $Pays, $Hors_taxe, $Devise ) ;
my ( $urlSrc, $urlExe ) = download_urls( $Date ) ;
my $tex_variables = qq{
%% Begin input from $0
\\providecommand{\\invoiceNumber}{$invoice}
\\providecommand{\\clientName}{$Nom}
\\providecommand{\\clientEmail}{$De_l_adresse_email}
\\providecommand{\\clientTypeEN}{$clientTypeEN}
\\providecommand{\\clientTypeFR}{$clientTypeFR}
\\providecommand{\\clientAdrA}{$clientAdrA}
\\providecommand{\\clientAdrB}{$clientAdrB}
\\providecommand{\\clientAdrC}{$clientAdrC}
\\providecommand{\\clientAdrD}{$clientAdrD}
\\providecommand{\\clientAdrE}{$clientAdrE}
\\providecommand{\\clientAdrF}{$clientAdrF}
\\providecommand{\\invoiceDate}{$Date}
\\providecommand{\\invoiceHour}{$Heure}
\\providecommand{\\priceHT}{$priceHT}
\\providecommand{\\tvaFR}{$tvaFR}
\\providecommand{\\tvaEN}{$tvaEN}
\\providecommand{\\priceTVA}{$priceTVA}
\\providecommand{\\priceTTC}{$priceTTC}
\\providecommand{\\priceTTCusd}{$priceTTCusd}
\\providecommand{\\messageTVAFR}{$messageTVAFR}
\\providecommand{\\messageTVAEN}{$messageTVAEN}
\\providecommand{\\urlSrc}{\\url{$urlSrc}}
\\providecommand{\\urlExe}{\\url{$urlExe}}
%% End input from $0
} ;
#print $tex_variables ;
write_tex_variables_file( $dir_invoices,
$invoice, $Date, $tex_variables ) if $write_invoices ;
}
sub build_email_message {
my ( $date, $name, $email, $invoice ) = @_ ;
my $message_header = qq{X-imapsync: invoice $invoice
From: Gilles LAMIRAL <gilles.lamiral\@laposte.net>
Bcc: gilles\@lamiral.info
Subject: [imapsync invoice] $invoice ($date)
Disposition-Notification-To: Gilles LAMIRAL <gilles.lamiral\@laposte.net>
} ;
my $message_body = qq{
Hello $name,
First I'm sorry for the delay to prepare and send you this message.
Attached is the invoice of imapsync software you bought ($date).
The invoice file is named facture_imapsync-${invoice}.pdf
This invoice is in PDF format, ready to be print.
If you need this invoice on paper, just ask me then
I will send it to you by postal mail.
In order to respect the law, this numeric invoice PDF
file is signed with my private gpg key.
The resulting gpg signature is in the file named
facture_imapsync-${invoice}.pdf.asc
also attached in this email message.
You can verify I (Gilles LAMIRAL) really generated
this invoice with the following command line
gpg --verify facture_imapsync-${invoice}.pdf.asc facture_imapsync-${invoice}.pdf
or any other gpg graphical tool.
I thank you again for buying and using imapsync.
Any feedback is welcome.
--
Au revoir, 09 51 84 42 42
Gilles Lamiral. France, Baulon (35580) 06 20 79 76 06
} ;
my $message_body_blabla = qq{
Here is the fingerprint of my public key
pub 1024D/FDA2B3DC 2002-05-08
Key fingerprint = 7906 F53D 0D62 0C67 304A 4CF0 6928 869B FDA2 B3DC
uid Gilles LAMIRAL <gilles.lamiral\@laposte.net>
sub 1024g/A2C4CB42 2002-05-08
Of course the verification doesn't prove anything until
all the following conditions are met:
- you met me,
- I agree that the fingerprint above is really mine
- I prove I'm Gilles LAMIRAL with an official paper.
Normally we won't have to verify anything unless
I disagree with this invoice and the payment
you made for imapsync.
} ;
return( $message_header, $message_body ) ;
}
sub write_csv_info {
my( $dir_invoices, $invoice, $file_csv, $line_number, $line_csv ) = @_ ;
open( CSVINFO, "> $dir_invoices/$invoice/csv_info.txt") or die ;
print CSVINFO join( "\n", $file_csv, $line_number, $line_csv ) ;
close( CSVINFO ) ;
}
sub write_email_message {
my ( $dir_invoices, $invoice, $message_header, $message_body, $email_address ) = @_ ;
my $message_body_utf8 = to_utf8({ -string => $message_body, -charset => 'ISO-8859-1' });
mkdir( "$dir_invoices/$invoice" ) or die if ! -d "$dir_invoices/$invoice" ;
open( HEADER, "> $dir_invoices/$invoice/facture_message_header.txt") or die ;
print HEADER $message_header ;
close( HEADER ) ;
open( BODY, "> $dir_invoices/$invoice/facture_message_body.txt") or die ;
print BODY $message_body_utf8 ;
close( BODY ) ;
open( ADDRESS, "> $dir_invoices/$invoice/email_address.txt") or die ;
print ADDRESS "$email_address\n" ;
close( ADDRESS ) ;
}
sub write_tex_variables_file {
my ( $dir_invoices, $invoice, $date_jjSmmSaaaa, $tex_variables ) = @_ ;
my $tex_variables_utf8 = to_utf8({ -string => $tex_variables, -charset => 'ISO-8859-1' });
mkdir( "$dir_invoices/$invoice" ) or die if ! -d "$dir_invoices/$invoice" ;
open( FILE, "> $dir_invoices/$invoice/imapsync_var.tex") or die ;
print FILE $tex_variables_utf8 ;
close( FILE ) ;
}
sub download_urls {
my $date_jjSmmSaaaa = shift ;
my $date_aaaa_mm_jj = date_aaaa_mm_jj( $date_jjSmmSaaaa ) ;
# print "$date_aaaa_mm_jj $date_jjSmmSaaaa\n" ;
my ( $urlSrc, $urlExe ) ;
if ('2011_03_24' le $date_aaaa_mm_jj) {
$urlSrc = 'http://www.linux-france.org/prj/imapsync/paypal_return.shtml' ;
$urlExe = '' ;
return( $urlSrc, $urlExe ) ;
}
if ('2011_02_21' le $date_aaaa_mm_jj) {
$urlSrc = 'http://www.linux-france.org/depot/2011_02_21/OUMbo7/' ;
$urlExe = 'http://www.linux-france.org/depot/2011_02_21/rHSVNs/' ;
return( $urlSrc, $urlExe ) ;
}
if ('2011_01_18' le $date_aaaa_mm_jj) {
$urlSrc = 'http://www.linux-france.org/depot/2011_01_18/zPRRNt/' ;
$urlExe = 'http://www.linux-france.org/depot/2011_01_18/FO1QzG/' ;
return( $urlSrc, $urlExe ) ;
}
if ('2011_01_18' le $date_aaaa_mm_jj) {
$urlSrc = 'http://www.linux-france.org/depot/2010_11_28/SiNdlZ/' ;
$urlExe = 'http://www.linux-france.org/depot/2010_11_28/R3ZAyr/' ;
return( $urlSrc, $urlExe ) ;
}
$urlSrc = 'http://www.linux-france.org/depot/2010_11_08/X2PWMe/' ;
$urlExe = 'http://www.linux-france.org/depot/2010_11_08/ZZ7zSc/' ;
return( $urlSrc, $urlExe ) ;
}
sub date_aaaa_mm_jj {
my $date_jjSmmSaaaa = shift ;
if ( $date_jjSmmSaaaa =~ m{(\d\d)/(\d\d)/(\d\d\d\d)} ) {
my( $jj, $mm, $aaaa ) = ( $1, $2, $3 ) ;
return( join( '_', $aaaa, $mm, $jj ) ) ;
}else{
return( '9999_12_31' ) ;
}
}
sub tva_stuff {
my( $clientTypeEN, $Pays, $Hors_taxe, $Devise ) = @_ ;
my $priceTTCusd = '' ;
$Hors_taxe =~ s{,}{.} ;
if ( $Devise eq 'USD' ) {
$priceTTCusd = "(USD $Hors_taxe)" ;
$Hors_taxe = ( $Hors_taxe/$usdeur ) ;
}
my (
$priceHT,
$tvaFR,
$tvaEN,
$priceTVA,
$priceTTC,
$messageTVAFR,
$messageTVAEN,
) ;
if ( ( 'individual' eq $clientTypeEN)
or
( 'France' eq $Pays )
) {
$priceHT = sprintf('%2.2f', $Hors_taxe/1.196) ;
$tvaFR = '19,60\%';
$tvaEN = '';
$priceTVA = sprintf('%2.2f', $Hors_taxe/1.196*0.196) ;
$priceTTC = sprintf('%2.2f', $Hors_taxe) ;
$messageTVAFR = '';
$messageTVAEN = '';
}else{
$priceHT = sprintf('%2.2f', $Hors_taxe) ;
$tvaFR = 'néant';
$tvaEN = '(none)';
$priceTVA = 0 ;
$priceTTC = $priceHT;
$messageTVAFR = 'Exonération de TVA, article 259 B-1 du Code Général des Impôts';
$messageTVAEN = '(VAT tax-exempt, article 259 B-1 French General Tax Code)';
}
foreach my $price ( $priceHT, $priceTVA, $priceTTC, $priceTTCusd ) {
#print "[$price]\n" ;
$price =~ s{\.}{, } ;
}
return(
$priceHT,
$tvaFR,
$tvaEN,
$priceTVA,
$priceTTC,
$messageTVAFR,
$messageTVAEN,
$priceTTCusd
) ;
}
sub client_type {
my ( $Nom_Option_1, $Valeur_Option_1 ) = @_ ;
my ( $clientTypeEN, $clientTypeFR ) = ( 'professional', 'professionnel' ) ;
if ('imapsync usage' eq $Nom_Option_1 and 'individual' eq $Valeur_Option_1 ) {
$clientTypeEN = 'individual' ;
$clientTypeFR = 'individuel' ;
}elsif ('imapsync usage' eq $Nom_Option_1 and 'professional' eq $Valeur_Option_1 ) {
$clientTypeEN = 'professional' ;
$clientTypeFR = 'professionnel' ;
}
return( $clientTypeEN, $clientTypeFR ) ;
}
sub build_adress {
my(
$Nom,
$Adresse_1,
$Adresse_2_district_quartier,
$Ville,
$Code_postal,
$Etat_Province,
$Pays,
) = @_ ;
my $addr = "
===========================================================
Nom $Nom
Adresse_1 $Adresse_1
Adresse_2_district_quartier $Adresse_2_district_quartier
Ville Code_postal $Ville $Code_postal
Etat_Province $Etat_Province
Pays $Pays
" ;
#print $addr ;
my @address ;
$Nom = '' if ( $Nom =~ m/^\s+$/ ) ;
push( @address, $Nom ) if $Nom ;
push( @address, $Adresse_1 ) if $Adresse_1 ;
push( @address, $Adresse_2_district_quartier ) if $Adresse_2_district_quartier ;
push( @address, "$Ville $Code_postal" ) if ( $Ville or $Code_postal );
push( @address, $Etat_Province ) if $Etat_Province ;
push( @address, $Pays, ) if $Pays ;
my $clientAdrA = shift( @address ) || '' ;
my $clientAdrB = shift( @address ) || '' ;
my $clientAdrC = shift( @address ) || '' ;
my $clientAdrD = shift( @address ) || '' ;
my $clientAdrE = shift( @address ) || '' ;
my $clientAdrF = shift( @address ) || '' ;
$addr = "
[$clientAdrA]
[$clientAdrB]
[$clientAdrC]
[$clientAdrD]
[$clientAdrE]
[$clientAdrF]
";
#print $addr ;
return(
$clientAdrA,
$clientAdrB,
$clientAdrC,
$clientAdrD,
$clientAdrE,
$clientAdrF,
) ;
}

View File

@ -1,83 +0,0 @@
#!/bin/sh
# usage: sh paypal_build_invoices/g/var/paypal_invoices/???
cp /home/gilles/public_html/AGIL/factures/000/facture_imapsync-000.tex /g/var/paypal_invoices/
set -x
/g/public_html/imapsync/paypal_reply/paypal_bilan --write_invoices --first_in 147 /g/paypal/paypal_2010_11_complet.csv
/g/public_html/imapsync/paypal_reply/paypal_bilan --write_invoices --first_in 214 /g/paypal/paypal_2010_12_complet.csv
/g/public_html/imapsync/paypal_reply/paypal_bilan --write_invoices --first_in 294 /g/paypal/paypal_2011_01_complet.csv
/g/public_html/imapsync/paypal_reply/paypal_bilan --write_invoices --first_in 382 /g/paypal/paypal_2011_02_complet.csv
/g/public_html/imapsync/paypal_reply/paypal_bilan --write_invoices --first_in 473 /g/paypal/paypal_2011_03_complet.csv
set +x
# USD de 147 à 340
# EUR de 341 à ...
# 20110413 Found problems with 189 199 249 258 263 359 537
# 20110412 Found problems with 189 199 242 249 258 263 359 382 537
# cen cen JAP cen cen cen cen TCH JAP
# cen
# 155 TVA 1,89
# 171 TVA 4,42
# 220 TVA 3,16
# 225 TVA 3,16
# 236 TVA 4,42
# 298 TVA 3,16
# 307 TVA 4,42
# 312 TVA 4,42
# 324 TVA 4,42
# 351 TVA 4,92
# 395 TVA 4,92
# 408 TVA 4,92
# 419 TVA 4,92
# 432 TVA 4,92
# 435 TVA 4,92
# 452 TVA 4,92
# 460 TVA 4,92
# 461 TVA 4,92
# 463 TVA 4,92
# 464 TVA 4,92
# 475 TVA 4,92
# 487 TVA 4,92
# 489 TVA 4,92
# 502 TVA 4,92
# 504 TVA 4,92
# 511 TVA 4,92
# 522 TVA 4,92
# 523 TVA 4,92
# 533 TVA 4,92
# 537 TVA 4,92
# 540 TVA 4,92
# 543 TVA 4,92
# 549 TVA 4,92
# 551 TVA 4,92
# 552 TVA 4,92
# 556 TVA 4,92
# 563 TVA 4,92
for d in "$@"; do
echo "==== $d ===="
cd $d
bd=`basename $d`
ln -f ../facture_imapsync-000.tex facture_imapsync-$bd.tex;
if ! pdflatex facture_imapsync-$bd.tex < /dev/null > /dev/null; then
echo "PB $bd"
if test -f facture_imapsync-${bd}_good.tex \
&& pdflatex facture_imapsync-${bd}_good.tex < /dev/null > /dev/null
then
ln -f facture_imapsync-${bd}_good.pdf facture_imapsync-$bd.pdf
echo "PB $bd solved with manual facture_imapsync-${bd}_good.tex"
PB_LIST_MANUAL="$PB_LIST_MANUAL $bd"
else
PB_LIST="$PB_LIST $bd"
rm -f facture_imapsync-$bd.pdf
continue
fi
fi
gpg --use-agent --armor --detach-sign --yes facture_imapsync-$bd.pdf
done
echo "Found problems with $PB_LIST"
echo "Manual invoices for $PB_LIST_MANUAL"

View File

@ -1,160 +0,0 @@
#!/usr/bin/perl
# $Id: paypal_build_reply,v 1.12 2011/03/23 18:31:52 gilles Exp gilles $
use warnings;
use strict;
use Getopt::Long;
my ($msg_id_file, $msg_id);
my ($amount, $name, $email);
my (
$paypal_line, $paypal_info,
$buyer, $description,
$url_source, $url_exe, $url, $release,
);
my $help ;
my $debug ;
my $numopt = scalar(@ARGV);
my $opt_ret = GetOptions(
"help" => \$help,
"debug!" => \$debug,
);
usage() and exit if ($help or ! $numopt) ;
$msg_id_file = $ARGV[1];
$msg_id = firstline($msg_id_file);
$debug and print "Hi!\n" ;
while(<>) {
next if ( ! /^(.*Num.+ro de transaction.*)$/ );
$paypal_line = $1;
$paypal_info = "===== Paypal id =====\n$paypal_line\n";
$debug and print "$paypal_info" ;
last;
}
while(<>) {
if ( /^Vous avez re.*paiement d'un montant de (.*) de la part de (.*) \((.*)\)/) {
($amount, $name, $email) = ($1, $2, $3);
last;
}
if ( /^Vous avez re.*paiement d'un montant de (.*) de la part de (.*)/) {
($amount, $name, $email) = ($1, "", $2);
last;
}
}
$url_source = firstline('/g/var/paypal_reply/url_source');
$url_exe = firstline('/g/var/paypal_reply/url_exe');
$release = firstline('/g/var/paypal_reply/url_release');
#print "[$amount] [$name] [$email] [$paypal_line]\n";
while(<>) {
if ( /^Acheteur/ ) {
$buyer .= "===== Acheteur =====\n";
last;
}
if ( /^Informations sur l'acheteur/ ) {
$buyer .= "===== Acheteur =====\n";
chomp( $name = <> );
$buyer .= "$name\n" ;
last;
}
}
while(<>) {
$buyer .= $_ if ( ! /^-----------------------------------/ );
last if ( /^-----------------------------------/ );
}
while(<>) {
next if ( ! /^Description :(.*)/ );
$description = "===== Details =====\n";
$description .= $_;
last;
}
while(<>) {
$debug and print "LINE:$_" ;
$description .= $_;
last if ( /^Paiement envoy/ );
last if ( /^N.*d'avis de r.*ception/ );
}
my $address = 'gilles.lamiral@laposte.net';
my $address2 = 'gilles@lamiral.info';
my $rcstag = '$Id: paypal_build_reply,v 1.12 2011/03/23 18:31:52 gilles Exp gilles $';
my $message = <<EOM
X-Comment: $rcstag
In-Reply-To: $msg_id
From: Gilles LAMIRAL <$address>
To: <$email>
Bcc: Gilles LAMIRAL <$address>, <$address2>
Subject: [imapsync download] imapsync release $release [$email]
Hello $name,
You will find the latest imapsync source code release $release at the following link:
$url_source
You will find the latest imapsync.exe binary release $release at the following link:
$url_exe
You will receive an invoice soon.
Next imapsync releases will be available for one year without extra payment.
Just keep this message and ask for the new links.
(I will build an automatic subscription tool later)
I thank you for buying and using imapsync,
I wish you successful transfers!
$paypal_info
$buyer
$description
==== Vendeur ====
Gilles LAMIRAL
4 La Billais
35580 Baulon
FRANCE
Tel: +33 951 84 42 42
Mob: +33 620 79 76 06
Fax: +33 956 84 42 42
email: $address
--
Au revoir, 09 51 84 42 42
Gilles Lamiral. France, Baulon (35580) 06 20 79 76 06
EOM
;
=pod
=cut
print $message;
#print "[$amount] [$name] [$email] [$paypal_line]\n";
sub firstline {
# extract the first line of a file (without \n)
my($file) = @_;
my $line = "";
open FILE, $file or die("error [$file]: $! ");
chomp($line = <FILE>);
close FILE;
$line = ($line) ? $line: "error !EMPTY! [$file]";
return $line;
}

View File

@ -1,227 +0,0 @@
#!/bin/sh
# $Id: paypal_functions,v 1.15 2011/03/23 19:10:56 gilles Exp gilles $
paypal_prerequisites() {
perl -mMIME::Lite -e '' || echo 'sudo aptitude install libmime-lite-perl'
perl -mMIME::Parser -e '' || echo 'sudo aptitude install libmime-tools-perl'
perl -mUnicode::MapUTF8 -e '' || echo 'sudo aptitude install libunicode-maputf8-perl'
}
paypal_init_laposte() {
user=gilles.lamiral
passfile=/g/var/pass/secret.gilles_laposte
host=imap.laposte.net
tmpdir=/g/var/paypal_reply
folder=INBOX
}
paypal_init_petite() {
user=gilles@est.belle
passfile=/g/var/pass/secret.gilles_mbox
host=p
tmpdir=/g/var/paypal_reply
folder='INBOX.03_imapsync.imapsync_paypal'
}
paypal_init_petite_INBOX() {
user=gilles@est.belle
passfile=/g/var/pass/secret.gilles_mbox
host=p
tmpdir=/g/var/paypal_reply
folder='INBOX'
}
paypal_init_petite_dev() {
user=gilles@est.belle
passfile=/g/var/pass/secret.gilles_mbox
host=p
tmpdir=/g/var/paypal_reply_dev
folder='INBOX.03_imapsync.imapsync_paypal_dev'
}
get_mail() {
# creation des répertoires
mkdir -p $tmpdir/msg_in/
mkdir -p $tmpdir/msg_id/
(
cd $tmpdir/msg_in/
# recuperation des messages de la boite sans destruction des messages
# transférés
paypal_imapget --host $host --user $user --passfile $passfile \
--folder $folder
)
}
get_mail_PP1470() {
# creation des répertoires
mkdir -p $tmpdir/msg_in/
mkdir -p $tmpdir/msg_id/
(
cd $tmpdir/msg_in/
# recuperation des messages de la boite sans destruction des messages
# transférés
paypal_imapget --host $host --user $user --passfile $passfile \
--folder $folder --search TEXT --search PP1470
)
}
extract_mail() {
mkdir -p $tmpdir/msg_out/
test -z "`ls $tmpdir/msg_in/`" && echo no mail && return
(
cd $tmpdir/msg_out/
test -z "`ls .`" || rm -rf *_d
paypal_mimeexplode ../msg_in/*
)
#ls -d $tmpdir/msg_out/
}
convert_utf8() {
mkdir -p $tmpdir/msg_out_utf8/
test -z "`ls $tmpdir/msg_out/`" && echo no mail && return
for f in $tmpdir/msg_out/*_d/*.txt; do
b=`basename "$f"`
d=`dirname "$f"`
bd=`basename "$d"`
d_utf8="$tmpdir/msg_out_utf8/$bd"
f_utf8="$d_utf8/$b"
test -d "$d_utf8" && continue
mkdir "$d_utf8"
if file "$f" | grep -i UTF-8 > /dev/null
then
echo copying "$f" to "$f_utf8"
cp "$f" "$f_utf8"
else
echo converting "$f" to "$f_utf8"
8859_utf8 "$f" > "$f_utf8"
fi
done
}
troncate_last_2_chars() {
length=`expr length "$1"`
length_2=`expr $length - 2`
expr substr "$1" 1 $length_2
}
build_reply() {
mkdir -p $tmpdir/msg_reply/
for f in $tmpdir/msg_out_utf8/*/*.txt; do
#echo "$f"
d=`dirname "$f"`
bd=`basename "$d"`
file_id=`troncate_last_2_chars $bd`
d_reply="$tmpdir/msg_reply/$file_id"
test -f "$d_reply/$file_id.txt" && continue
mkdir -p "$d_reply"
echo building "$d_reply/$file_id.txt"
paypal_build_reply "$f" "$tmpdir/msg_id/$file_id" > "$d_reply/$file_id.txt"
done
}
build_reply_arg() {
for f in "$@"; do
#echo "$f"
d=`dirname "$f"`
bd=`basename "$d"`
file_id=`troncate_last_2_chars $bd`
d_reply="$tmpdir/msg_reply/$file_id"
echo building "$d_reply/$file_id.txt"
echo paypal_build_reply "$f" "$tmpdir/msg_id/$file_id"
paypal_build_reply "$f" "$tmpdir/msg_id/$file_id"
done
}
send_reply() {
mkdir -p $tmpdir/msg_sent/
for f in $tmpdir/msg_reply/*/*.txt; do
b=`basename "$f"`
d=`dirname "$f"`
bd=`basename "$d"`
d_sent="$tmpdir/msg_sent/$bd"
test -f "$d_sent/$b" && continue
mkdir -p "$d_sent"
test X"--send" = X"$1" && paypal_send --send "$f" && touch "$d_sent/$b"
#test X"--send" = X"$1" && touch "$d_sent/$b"
test X"" = X"$1" && paypal_send "$f"
done
mailq
}
paypal_all() {
paypal_prerequisites
echo "Will get messages in $tmpdir/msg_in/"
get_mail
get_mail_PP1470
echo "Done get messages in $tmpdir/msg_in/"
echo "Will extract_mail in $tmpdir/msg_out/"
extract_mail
echo "Done extract_mail in $tmpdir/msg_out/"
echo "Will converting to utf8 in $tmpdir/msg_out_utf8/"
convert_utf8
echo "Done converting to utf8 in $tmpdir/msg_out_utf8/"
echo "Will build_reply in $tmpdir/msg_reply/"
build_reply
echo "Done build_reply in $tmpdir/msg_reply/"
echo "Will send_reply $@"
send_reply "$@"
echo "Done send_reply $@"
}
#echo 'paypal_reply_petite'
paypal_reply_petite() {
echo "Doing paypal_reply_petite"
echo paypal_init_petite
paypal_init_petite
paypal_all "$@"
echo paypal_init_petite_INBOX
paypal_init_petite_INBOX
paypal_all "$@"
echo "Done paypal_reply_petite"
}
#echo 'paypal_reply_laposte'
paypal_reply_laposte() {
echo "Doing paypal_reply_laposte"
echo paypal_init_laposte
paypal_init_laposte
paypal_all "$@"
echo "Done paypal_reply_laposte"
}
paypal_all_dev() {
paypal_prerequisites
echo "Will get messages in $tmpdir/msg_in/"
get_mail_PP1470
echo "Done get messages in $tmpdir/msg_in/"
echo "Will extract_mail in $tmpdir/msg_out/"
extract_mail
echo "Done extract_mail in $tmpdir/msg_out/"
echo "Will converting to utf8 in $tmpdir/msg_out_utf8/"
convert_utf8
echo "Done converting to utf8 in $tmpdir/msg_out_utf8/"
echo "Will build_reply in $tmpdir/msg_reply/"
build_reply
echo "Done build_reply in $tmpdir/msg_reply/"
echo "Will send_reply $@"
send_reply "$@"
echo "Done send_reply $@"
}
paypal_reply_petite_dev() {
echo "Doing paypal_reply_petite_dev"
echo paypal_init_petite_dev
paypal_init_petite_dev
paypal_all_dev "$@"
echo "Done paypal_reply_petite_dev"
}

View File

@ -1,134 +0,0 @@
#!/usr/bin/perl -w
# $Id: paypal_imapget,v 1.7 2011/03/23 17:05:24 gilles Exp gilles $
use Getopt::Long;
use Mail::IMAPClient;
use FileHandle;
my $host;
my $port = 143;
my $debugimap = 0;
my $debug = 0;
my $user;
my $password;
my $passfile;
my $folder = 'INBOX';
my @search ;
my $help;
my $numopt = scalar(@ARGV);
my $opt_ret = GetOptions(
"host=s" => \$host,
"user=s" => \$user,
"password=s" => \$password,
"passfile=s" => \$passfile,
"folder=s" => \$folder,
"search=s" => \@search,
"help" => \$help,
"delete!" => \$delete,
"expunge!" => \$expunge,
"debugimap!" => \$debugimap,
"debug!" => \$debug,
);
usage() and exit if ($help or ! $numopt) ;
$password = (defined($passfile)) ? firstline ($passfile) : $password;
my $imap = Mail::IMAPClient->new();
$imap->Server($host);
$imap->Port($port);
$imap->Uid(1);
$imap->Peek(1);
$imap->Debug($debugimap);
$imap->connect()
or die "Can not open imap connection on [$host] with user [$user] : $@\n";
$imap->User($user);
$imap->Password($password);
$imap->login() or die "Error login : [$host] with user [$user] : $@";
$imap->select($folder) or die "Error select folder [$folder] host [$host] user [$user] : $@";
#my @uids = $imap->search('HEADER', 'SUBJECT',"=?windows-1252?Q?Avis_de_r=E9ception_d=27un_paiement?=");
#my @uids = $imap->search('HEADER', 'Sender','sendmail@paypal.com');
#my @uids = $imap->search('TEXT', 'PP341');
print "@search\n" ;
@search = ('TEXT', 'PP341') if not @search ;
my @uids = $imap->search('HEADER', 'Sender','sendmail@paypal.com', @search );
print "Search: [@uids]\n";
foreach $msg (@uids) {
my $msg_id = $imap->get_header( $msg, "Message-Id" );
$debug and print "$msg_id\n";
my $msg_code = format_msg_id($msg_id);
my $file = "$msg_code";
if (-f $msg_code and -f "../msg_id/$msg_code") {
$debug and print "Already have $msg_code $msg\n";
next;
}
print "writing message $msg to $file\n";
unlink($file);
if ($imap->message_to_file($file, $msg)) {
$imap->delete_message($msg) if $delete;
$imap->expunge() if $expunge;
}else{
print "Error writing $file: $@\n";
}
write_to_file("../msg_id/$msg_code", $msg_id);
}
$imap->logout();
sub usage {
print <<EOF;
usage: $0 [options]
Several options are mandatory.
--host <string> : imap server. Mandatory.
--user <string> : user to login. Mandatory.
--password <string> : password for the user1. Mandatory.
--delete : mark messages well dumped as deleted
--expunge : expunge folder.
Example:
$0 \\
--host imap.troc.org --user foo --password secret
EOF
}
sub firstline {
# extract the first line of a file (without \n)
my($file) = @_;
my $line = "";
open FILE, $file or die("error [$file]: $! ");
chomp($line = <FILE>);
close FILE;
$line = ($line) ? $line: "error !EMPTY! [$file]";
return $line;
}
sub format_msg_id {
my $msg_id = shift;
$msg_id =~ tr/a-zA-Z0-9/_/cs;
$debug and print "$msg_id\n";
return($msg_id);
}
sub write_to_file {
my $file = shift;
my $string = shift;
$fh = FileHandle->new("> $file");
if (defined $fh) {
print $fh $string;
$fh->close;
}
}

View File

@ -1,187 +0,0 @@
#!/usr/bin/perl -w
# $Id: paypal_mimeexplode,v 1.1 2010/11/23 01:26:24 gilles Exp gilles $
=head1 NAME
mimeexplode - explode one or more MIME messages
=head1 SYNOPSIS
mimeexplode <mime-msg-file> <mime-msg-file> ...
someprocess | mimeexplode -
=head1 DESCRIPTION
Takes one or more files from the command line that contain MIME
messages, and explodes their contents out into subdirectories
of the current working directory. The subdirectories are
just called C<msg0>, C<msg1>, C<msg2>, etc. Existing directories are
skipped over.
The message information is output to the stdout, like this:
Message: msg3 (inputfile1.msg)
Part: msg3/filename-1.dat (text/plain)
Part: msg3/filename-2.dat (text/plain)
Message: msg5 (input-file2.msg)
Part: msg5/dir.gif (image/gif)
Part: msg5/face.jpg (image/jpeg)
Message: msg6 (infile3)
Part: msg6/filename-1.dat (text/plain)
This was written as an example of the MIME:: modules in the
MIME-parser package I wrote. It may prove useful as a quick-and-dirty
way of splitting a MIME message if you need to decode something, and
you don't have a MIME mail reader on hand.
=head1 COMMAND LINE OPTIONS
None yet.
=head1 AUTHOR
Eryq C<eryq@zeegee.com>, in a big hurry...
=cut
BEGIN { unshift @INC, ".." } # to test MIME:: stuff before installing it!
require 5.001;
use strict;
use Getopt::Long;
use vars qw($Msgno);
use MIME::Parser;
use Getopt::Std;
use File::Basename;
my $numopt = scalar(@ARGV);
my $help;
my $debug;
my $opt_ret = GetOptions(
"help" => \$help,
"debug!" => \$debug,
);
usage() and exit if ($help or ! $numopt) ;
sub usage {
print <<EOF;
Usage: $0 [options] email_1 email_2 ...
Options:
--help : print this message
--debug : verbose output
Example:
$0 email_1 email_2
EOF
}
#------------------------------------------------------------
# make_msg - make and return the name of a msgXXX directory
#------------------------------------------------------------
$Msgno = 1;
sub make_msg {
while (-d "msg$Msgno") {
++$Msgno;
die "self-imposed limit reached" if $Msgno == 256;
}
mkdir "msg$Msgno",0755 or die "couldn't make msg$Msgno: $!";
"msg$Msgno";
}
#------------------------------------------------------------
# make_msg_dir - make and return the name of a output directory
#------------------------------------------------------------
sub make_msg_dir {
my ($file) = @_;
if ("-" ne "$file") {
my $basefile = basename($file) . "_d";
-d $basefile and return($basefile);
mkdir $basefile or do {
warn "can not create directory $basefile: $!";
return undef;
};
return($basefile);
}else{
return(make_msg());
}
}
#------------------------------------------------------------
# dump_entity - dump an entity's file info
#------------------------------------------------------------
sub dump_entity {
my $ent = shift;
my @parts = $ent->parts;
if (@parts) { # multipart...
map { dump_entity($_) } @parts;
}
else { # single part...
$debug and print " Part: ", $ent->bodyhandle->path,
" (", scalar($ent->head->mime_type), ")\n";
}
}
#------------------------------------------------------------
# main
#------------------------------------------------------------
sub main {
my $file;
my $entity;
# Sanity:
(-w ".") or die "cwd not writable, you naughty boy...";
# Go through messages:
@ARGV or unshift @ARGV, "-";
while (defined($file = shift @ARGV)) {
my $msgdir = make_msg_dir($file);
next if not $msgdir;
$debug and print "Message: $msgdir ($file)\n";
# Create a new parser object:
my $parser = new MIME::Parser;
### $parser->parse_nested_messages('REPLACE');
# Optional: set up parameters that will affect how it extracts
# documents from the input stream:
$parser->output_dir($msgdir);
# Parse an input stream:
open FILE, $file or die "couldn't open $file";
$entity = $parser->read(\*FILE) or
print STDERR "Couldn't parse MIME in $file; continuing...\n";
close FILE;
# Congratulations: you now have a (possibly multipart) MIME entity!
dump_entity($entity) if $entity;
### $entity->dump_skeleton if $entity;
}
1;
}
exit (&main ? 0 : -1);
#------------------------------------------------------------
1;

View File

@ -1,30 +0,0 @@
#!/bin/sh
# $Id: paypal_run_dev,v 1.4 2011/03/23 19:08:30 gilles Exp gilles $
set -e
#set -x
# Add path to commands at home
PATH=$PATH:/g/public_html/imapsync/paypal_reply
PERL5LIB=/g/public_html/imapsync/Mail-IMAPClient-3.28/lib
export PERL5LIB
test -f /g/public_html/imapsync/paypal_reply/paypal_functions \
&& . /g/public_html/imapsync/paypal_reply/paypal_functions
DATE_1=`date`
echo "==== paypal_reply_test ===="
paypal_reply_petite_dev "$@"
echo
DATE_2=`date`
echo "Debut : $DATE_1"
echo "Fin : $DATE_2"
echo "Yo Bery GOOD !"

View File

@ -1,30 +0,0 @@
#!/bin/sh
# $Id: paypal_run_laposte,v 1.3 2011/03/23 17:02:39 gilles Exp $
set -e
#set -x
# Add path to commands at home
PATH=$PATH:/g/public_html/imapsync/paypal_reply
PERL5LIB=/g/public_html/imapsync/Mail-IMAPClient-3.28/lib
export PERL5LIB
test -f /g/public_html/imapsync/paypal_reply/paypal_functions \
&& . /g/public_html/imapsync/paypal_reply/paypal_functions
DATE_1=`date`
echo "==== paypal_reply_laposte ===="
paypal_reply_laposte "$@"
echo
DATE_2=`date`
echo "Debut : $DATE_1"
echo "Fin : $DATE_2"
echo "Yo Bery GOOD !"

View File

@ -1,30 +0,0 @@
#!/bin/sh
# $Id: paypal_run_petite,v 1.5 2011/03/23 17:02:39 gilles Exp $
set -e
#set -x
# Add path to commands at home
PATH=$PATH:/g/public_html/imapsync/paypal_reply
PERL5LIB=/g/public_html/imapsync/Mail-IMAPClient-3.28/lib
export PERL5LIB
test -f /g/public_html/imapsync/paypal_reply/paypal_functions \
&& . /g/public_html/imapsync/paypal_reply/paypal_functions
DATE_1=`date`
echo "==== paypal_reply_petite ===="
paypal_reply_petite "$@"
echo
DATE_2=`date`
echo "Debut : $DATE_1"
echo "Fin : $DATE_2"
echo "Yo Bery GOOD !"

View File

@ -1,71 +0,0 @@
#!/usr/bin/perl
# $Id: paypal_send,v 1.3 2010/12/29 23:50:24 gilles Exp gilles $
use strict;
use warnings;
use Getopt::Long;
use MIME::Lite;
my (
$help,
$debug,
$send,
);
my $numopt = scalar(@ARGV);
my $opt_ret = GetOptions(
"help" => \$help,
"debug!" => \$debug,
"send!" => \$send,
);
usage() and exit if ($help or ! $numopt or ! $opt_ret) ;
my @reply = <>;
my %header;
while (my $line = shift @reply) {
#print $line;
chomp($line);
last if ($line =~ /^$/) ;
my($blank, $key, $value) = split /^(.+?:)\s*/, $line;
#print "[$key] [$value]\n";
$header{$key} = $value;
}
my $data = join('', @reply);
#print "[", $data, "]\n";
my $message = MIME::Lite->new();
$message->attr("content-type" => "text/plain");
$message->attr("content-type.charset" => "UTF-8");
$message->build(%header);
$message->build(Data => $data);
$message->print(\*STDOUT);
if ($send) {
$message->send;
print "Sent to ", $header{'To:'},"\n";
}
sub usage {
print <<EOF;
usage: $0 [options] file
--help : print this help message
--debug : verbose output
--send : send message
Examples:
$0 file
$0 --send file
EOF
}

View File

@ -1,43 +0,0 @@
#!/bin/sh
# usages:
# sh paypal_send_invoices /g/var/paypal_invoices/147
# sh paypal_send_invoices /g/var/paypal_invoices/15?
send_invoice() {
test X"" = X"$1" && { echo "usage: send_invoice /g/var/paypal_invoices/147 vince@norestech.net"; return; }
d="$1"
echo "====== $d ======"
#echo
cd $d || return
bd=`basename $d`
#echo "$bd"
invoice="$bd"
test -f facture_imapsync-${invoice}.pdf || { echo NO facture_imapsync-${invoice}.pdf ; return; }
test -f facture_imapsync-${invoice}.pdf.asc || { echo NO facture_imapsync-${invoice}.pdf.asc ; return; }
test -f facture_message_header.txt || { echo NO facture_message_header.txt ; return; }
test -f facture_message_body.txt || { echo NO facture_message_body.txt ; return; }
test -f email_address.txt || { echo NO email_address.txt ; return; }
email=${2:-`cat email_address.txt`}
> facture_message_to.txt
egrep '^To: ' facture_message_header.txt > /dev/null || echo "To: $email" > facture_message_to.txt
cat facture_message_header.txt facture_message_to.txt facture_message_body.txt > facture_message.txt
more facture_message.txt
echo '====== END of message ======'
test -f "SENT_TO_$email" && { echo "Already SENT_TO_$email"; }
test -f "SENT_TO_$email" || acroread facture_imapsync-${invoice}.pdf&
echo "Send this invoice ${invoice} to $email?"
read r < /dev/tty
echo SAID "[$r]"
test X"$r" = Xy && {
echo | mutt -H facture_message.txt -a facture_imapsync-${invoice}.pdf facture_imapsync-${invoice}.pdf.asc --
touch SENT_TO_$email
}
}
for d in "$@"; do
send_invoice "$d"
done

View File

@ -5,7 +5,7 @@
<title>imapsync download</title>
<meta name="generator" content="Bluefish 1.0.7"/>
<meta name="author" content="Gilles LAMIRAL"/>
<meta name="date" content="2011-03-24T02:20:46+0100"/>
<meta name="date" content="2011-05-07T04:53:07+0200"/>
<meta name="copyright" content=""/>
<meta name="keywords" content=""/>
<meta name="description" content=""/>
@ -46,12 +46,12 @@ You may log into your account at <a href="http://www.paypal.com/">www.paypal.com
to view details of this transaction.
</p>
<p>You will find the latest <b>imapsync source code</b> release 1.404 at the following link:<br/>
<a href="http://www.linux-france.org/depot/2011_02_21/OUMbo7/">http://www.linux-france.org/depot/2011_02_21/OUMbo7/</a>
<p>You will find the latest <b>imapsync source code</b> release 1.417 at the following link:<br/>
<a href="http://www.linux-france.org/depot/2011_05_07/8qkE2L/">http://www.linux-france.org/depot/2011_05_07/8qkE2L/</a>
</p>
<p>You will find the latest <b>imapsync.exe binary</b> release 1.404 at the following link:<br/>
<a href="http://www.linux-france.org/depot/2011_02_21/rHSVNs/">http://www.linux-france.org/depot/2011_02_21/rHSVNs/</a>
<p>You will find the latest <b>imapsync.exe binary</b> release 1.417 at the following link:<br/>
<a href="http://www.linux-france.org/depot/2011_05_07/eQ5bXu/">http://www.linux-france.org/depot/2011_05_07/eQ5bXu/</a>
</p>
<p>You will receive an invoice soon.</p>
@ -82,7 +82,7 @@ gilles.lamiral@laposte.net</p>
<!--#config timefmt="%D" -->
<!--#config timefmt="%A %B %d, %Y" -->
<b>This document last modified on <!--#echo var="LAST_MODIFIED" --></b><br/>
($Id: paypal_return.shtml,v 1.2 2011/03/24 01:21:27 gilles Exp gilles $)
($Id: paypal_return.shtml,v 1.5 2011/05/07 02:56:35 gilles Exp gilles $)
</p>
<!-- Google Code for Achat imapsync Conversion Page -->

View File

@ -1,15 +0,0 @@
#!/usr/bin/perl -w
use Carp;
use Mail::IMAPClient;
$imap = Mail::IMAPClient->new(Debug => 1);
$imap->Debug(1);
$imap->Server('louloutte.dyndns.org');
$imap->connect() or croak "Error connecting @!";
$imap->User('MarkOv@est.belle');
$imap->Password('emhj91ly');
$imap->login();
$imap->logout();

View File

@ -1,16 +0,0 @@
Using Mail::IMAPClient version 2.2.9 and perl version 5.8.8 (5.008008)
Read: * OK [CAPABILITY IMAP4rev1 UIDPLUS CHILDREN NAMESPACE THREAD=ORDEREDSUBJECT THREAD=REFERENCES SORT QUOTA AUTH=PLAIN CRAM-MD5 CRAM-SHA1 IDLE STARTTLS] Courier-IMAP ready. Copyright 1998-2005 Double Precision, Inc. See COPYING for distribution information.
Connect: Received this from readline: 0/OUTPUT/* OK [CAPABILITY IMAP4rev1 UIDPLUS CHILDREN NAMESPACE THREAD=ORDEREDSUBJECT THREAD=REFERENCES SORT QUOTA AUTH=PLAIN CRAM-MD5 CRAM-SHA1 IDLE STARTTLS] Courier-IMAP ready. Copyright 1998-2005 Double Precision, Inc. See COPYING for distribution information.
Sending: 1 Login "XXXXXXXX" XXXXXXXX
Sent 37 bytes
Read: 1 OK LOGIN Ok.
Sending: 2 LOGOUT
Sent 10 bytes
Read: * BYE Courier-IMAP server shutting down
2 OK LOGOUT completed

View File

@ -1,35 +0,0 @@
#!/usr/bin/perl -w
use Carp;
use Mail::IMAPClient;
$imap = Mail::IMAPClient->new();
$imap->Debug(0);
$imap->Server('louloutte.dyndns.org');
$imap->connect() or croak "Error connecting $@ !";
$imap->User('MarkOv@est.belle');
$imap->Password('emhj91ly');
$imap->login() or croak "Error login $@ !";
$imap->Uid(1) or croak "Error Uid $@ !";
print "[", $imap->folders, "]\n";
$imap->select('Inbox') or croak "Could not select: $@ !";
my @messages = $imap->messages or croak "Could not get message list: $@ !";
print "[@messages]\n";
$message = $messages[1];
print "[$message]\n";
my $string = $imap->message_string($message);
print $string;
#my $uid = $imap->append_string('INBOX.Trash', $string, '\Seen', "30-Oct-2006 01:34:14 +0100")
# or croak "Could not append_string: $@\n";
my $uid = $imap->append_string('INBOX.Trash', "$string", '\Seen', "")
or croak "Could not append_string: $@\n";
print "$uid\n";
$imap->logout();

View File

@ -1,53 +0,0 @@
#!/usr/bin/perl -w
use Carp;
use Mail::IMAPClient;
use strict;
my $imap1 = Mail::IMAPClient->new();
$imap1->Debug(0);
$imap1->Server('louloutte.dyndns.org');
$imap1->connect() or croak "Error connecting $@ !";
$imap1->User('MarkOv@est.belle');
$imap1->Password('emhj91ly');
$imap1->login() or croak "Error login $@ !";
$imap1->Uid(1) or croak "Error Uid $@ !";
my $imap2 = Mail::IMAPClient->new();
$imap2->Debug(0);
$imap2->Server('louloutte.dyndns.org');
$imap2->connect() or croak "Error connecting $@ !";
$imap2->User('MarkOv@est.belle');
$imap2->User('titi@est.belle');
$imap2->Password('HUwtEd');
$imap2->login() or croak "Error login $@ !";
$imap2->Uid(1) or croak "Error Uid $@ !";
print "[", $imap1->folders, "]\n";
$imap1->select('Inbox') or croak "Could not select: $@ !";
$imap2->select('Inbox') or croak "Could not select: $@ !";
my @msg_id_2 = $imap2->messages;
my $msg_id_2 = $msg_id_2[1];
my $msg_id_1 = ($imap1->messages)[0];
print "msg_id_1: $msg_id_1\n";
my $string_2 = $imap2->message_string($msg_id_2);
print $string_2;
my $message_file_1 = "tmp_message_to_file_${$}_1";
my $message_file_2 = "tmp_message_to_file_${$}_2";
unlink($message_file_1);
unlink($message_file_2);
$imap2->message_to_file($message_file_2, $msg_id_2) or croak "Could not message_to_file";
$imap1->message_to_file($message_file_1, $msg_id_1) or croak "Could not message_to_file";
$imap1->logout();
$imap2->logout();

View File

@ -1,91 +0,0 @@
$RCSfile: imapsync,v $ $Revision: 1.244 $ $Date: 2008/02/29 22:43:22 $
Here is a [linux] system (Linux plume 2.6.20.3 #1 Sun Mar 25 06:07:36 CEST 2007 i686)
with perl 5.8.8 and the module Mail::IMAPClient version used here is 3.05
Command line used :
./imapsync --host1 localhost --user1 tata@est.belle --passfile1 /var/tmp/secret.tata --host2 localhost --user2 titi@est.belle --passfile2 /var/tmp/secret.titi --folder INBOX.Trash --syncinternaldates
will try to use CRAM-MD5 authentication on host1
will try to use CRAM-MD5 authentication on host2
From imap server [localhost] port [143] user [tata@est.belle]
To imap server [localhost] port [143] user [titi@est.belle]
Banner : * OK [CAPABILITY IMAP4rev1 UIDPLUS CHILDREN NAMESPACE THREAD=ORDEREDSUBJECT THREAD=REFERENCES SORT QUOTA AUTH=PLAIN CRAM-MD5 CRAM-SHA1 IDLE STARTTLS] Courier-IMAP ready. Copyright 1998-2005 Double Precision, Inc. See COPYING for distribution information.
Host localhost says it has CAPABILITY for AUTHENTICATE CRAM-MD5
Success login on [localhost] with user [tata@est.belle] auth [CRAM-MD5]
Banner : * OK [CAPABILITY IMAP4rev1 UIDPLUS CHILDREN NAMESPACE THREAD=ORDEREDSUBJECT THREAD=REFERENCES SORT QUOTA AUTH=PLAIN CRAM-MD5 CRAM-SHA1 IDLE STARTTLS] Courier-IMAP ready. Copyright 1998-2005 Double Precision, Inc. See COPYING for distribution information.
Host localhost says it has CAPABILITY for AUTHENTICATE CRAM-MD5
Success login on [localhost] with user [titi@est.belle] auth [CRAM-MD5]
From capability : QUOTA STARTTLS NAMESPACE CRAM-SHA1 IDLE AUTH=PLAIN THREAD=ORDEREDSUBJECT SORT UIDPLUS CHILDREN CRAM-MD5 IMAP4REV1 THREAD=REFERENCES
To capability : QUOTA STARTTLS NAMESPACE CRAM-SHA1 IDLE AUTH=PLAIN THREAD=ORDEREDSUBJECT SORT UIDPLUS CHILDREN CRAM-MD5 IMAP4REV1 THREAD=REFERENCES
From state Authenticated
To state Authenticated
From separator and prefix : [.][INBOX.]
To separator and prefix : [.][INBOX.]
++++ Calculating sizes ++++
From Folder [INBOX.Trash] Size: 1012 Messages: 1
Total size: 1012
Total messages: 1
Time : 1 s
++++ Calculating sizes ++++
To Folder [INBOX.Trash] Size: 0 Messages: 0
Total size: 0
Total messages: 0
Time : 0 s
++++ Listing folders ++++
From folders list : [INBOX.Trash]
To folders list : [INBOX.Trash]
++++ Looping on each folder ++++
From Folder [INBOX.Trash]
To Folder [INBOX.Trash]
++++ From [INBOX.Trash] Parse 1 ++++
++++ To [INBOX.Trash] Parse 1 ++++
++++ Verifying [INBOX.Trash] -> [INBOX.Trash] ++++
+ NO msg #2319 [1c8g+RBA0iMRz+/+c3pqXw:1012] in INBOX.Trash
+ Copying msg #2319:1012 to folder INBOX.Trash
AAAmessage_string[FCC: imap://tata%40est.belle@localhost/INBOX/Sent
X-Identity-Key: id2
Message-ID: <45454886.2030307@localhost>
Date: Mon, 30 Oct 2006 01:34:14 +0100
From: TATA <tata@localhost>
X-Mozilla-Draft-Info: internal/draft; vcard=0; receipt=0; uuencode=0
User-Agent: Thunderbird 1.5.0.4 (X11/20060722)
MIME-Version: 1.0
To: Gilles Lamiral <gilles@louloutte.dyndns.org>
Subject: Re: test:ophaifaibequahdu
References: <20030821153335.86EB6FCA2@louloutte.dyndns.org>
In-Reply-To: <20030821153335.86EB6FCA2@louloutte.dyndns.org>
Content-Type: text/html; charset=ISO-8859-1
Content-Transfer-Encoding: 7bit
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<meta content="text/html;charset=ISO-8859-1" http-equiv="Content-Type">
</head>
<body bgcolor="#ffffff" text="#000000">
Gilles Lamiral wrote:
<blockquote cite="mid20030821153335.86EB6FCA2@louloutte.dyndns.org"
type="cite">
<pre wrap="">test:ophaifaibequahdu
</pre>
</blockquote>
<br>
</body>
</html>
]ZZZ
AAA1[]ZZZ
flags from : [\Seen]["30-Oct-2006 01:34:14 +0100"]
Time : 0 s
++++ Statistics ++++
Time : 2 sec
Messages transferred : 0
Messages skipped : 0
Total bytes transferred: 0
Total bytes skipped : 0
Total bytes error : 1012
Detected 1 errors
Please, rate imapsync at http://freshmeat.net/projects/imapsync/
?Happy with this free, open source and gratis GPL software?
Feel free to thank the author by giving him a book:
http://www.amazon.com/gp/registry/wishlist/1C9UNDIH3P7R7/
(or its paypal account gilles.lamiral@laposte.net)

View File

@ -1,21 +0,0 @@
#!/usr/bin/perl -w
use Carp;
use Mail::IMAPClient;
$imap = Mail::IMAPClient->new(Debug => 1);
$imap->Debug(1);
$imap->Server('louloutte.dyndns.org');
$imap->connect() or croak "Error connecting @!";
$imap->User('MarkOv@est.belle');
$imap->Password('emhj91ly');
$imap->login();
$imap->select('Inbox');
my @messages = $imap->messages();
my $headers = $imap->parse_headers([@messages]);
$imap->logout();

View File

@ -1,26 +0,0 @@
#!/usr/bin/perl -w
use Carp;
use Mail::IMAPClient;
use IO::Socket::SSL;
my $ssl = new IO::Socket::SSL("louloutte.dyndns.org:993");
my $imap = Mail::IMAPClient->new();
$imap->Socket($ssl);
$imap->Debug(1);
$imap->Server('louloutte.dyndns.org');
$imap->connect() or croak "Error connecting @!";
$imap->User('MarkOv@est.belle');
$imap->Password('emhj91ly');
$imap->login();
$imap->select('Inbox');
my @messages = $imap->messages();
my $headers = $imap->parse_headers([@messages]);
$imap->logout();

View File

@ -1,26 +0,0 @@
#!/usr/bin/perl -w
use Carp;
use Mail::IMAPClient;
use IO::Socket::SSL;
my $ssl = new IO::Socket::SSL("louloutte.dyndns.org:993");
my $imap = Mail::IMAPClient->new();
$imap->Socket($ssl);
$imap->Debug(1);
$imap->Server('louloutte.dyndns.org');
$imap->connect() or croak "Error connecting @!";
$imap->User('titi@est.belle');
$imap->Password('HUwtEd');
$imap->login();
$imap->select('Inbox');
my @messages = $imap->messages();
my $headers = $imap->parse_headers([@messages]);
$imap->logout();

156
tests.sh
View File

@ -1,6 +1,6 @@
#!/bin/sh
# $Id: tests.sh,v 1.159 2011/04/20 01:18:40 gilles Exp gilles $
# $Id: tests.sh,v 1.163 2011/05/09 00:10:16 gilles Exp gilles $
# Example 1:
# CMD_PERL='perl -I./Mail-IMAPClient-3.25/lib' sh -x tests.sh
@ -257,6 +257,18 @@ ll_folder_create() {
--justfolders
}
ll_folder_create_INBOX_Inbox() {
$CMD_PERL ./imapsync \
--host1 $HOST1 --user1 tata \
--passfile1 ../../var/pass/secret.tata \
--host2 $HOST2 --user2 titi \
--passfile2 ../../var/pass/secret.titi \
--folder INBOX --regextrans2 's/INBOX/Inbox/' \
--justfolders
}
ll_oneemail() {
$CMD_PERL ./imapsync \
@ -449,12 +461,9 @@ ll_nosyncinternaldates() {
# 2.xx noidate: Sending: 62 APPEND INBOX {428}
ll_idatefromheader() {
if can_send; then
#echo3 Here is plume
sendtestmessage
else
:
fi
can_send && sendtestmessage
$CMD_PERL ./imapsync \
--host1 $HOST1 --user1 tata \
--passfile1 ../../var/pass/secret.tata \
@ -520,23 +529,58 @@ ll_dev_reconnect()
#
: <<'EOF'
while :; do
killall -u vmail imapd;
killall -v -u vmail imapd;
RAND_WAIT=`numrandom .1..5i.1`
echo sleeping $RAND_WAIT
sleepenh $RAND_WAIT
done
EOF
# or
while read y; do
killall -u vmail imapd;
done
$CMD_PERL ./imapsync \
EOF
can_send && sendtestmessage
# can_send && sendtestmessage
$CMD_PERL ./imapsync \
--host1 $HOST1 --user1 tata \
--passfile1 ../../var/pass/secret.tata \
--host2 $HOST2 --user2 titi \
--passfile2 ../../var/pass/secret.titi
#--folder INBOX
#--debug --debugimap
--passfile2 ../../var/pass/secret.titi \
--folder INBOX --useuid \
--delete2 --expunge2
}
ll_dev_reconnect_ssl_tls()
{
# in another terminal:
#
: <<'EOF'
while :; do
killall -v -u vmail imapd;
RAND_WAIT=`numrandom .1..5i.1`
echo sleeping $RAND_WAIT
sleepenh $RAND_WAIT
done
# or
while read y; do
echo ENTER to kill all imapd
killall -v -u vmail imapd;
done
EOF
can_send && sendtestmessage
# can_send && sendtestmessage
$CMD_PERL ./imapsync \
--host1 $HOST1 --ssl1 --user1 tata \
--passfile1 ../../var/pass/secret.tata \
--host2 $HOST2 --tls2 --user2 titi \
--passfile2 ../../var/pass/secret.titi \
--folder INBOX --useuid \
--delete2
}
ll_authmd5()
@ -631,22 +675,29 @@ ll_maxage_9999()
ll_maxsize()
{
if can_send; then
#echo3 Here is plume
sendtestmessage
else
:
fi
$CMD_PERL ./imapsync \
{
can_send && sendtestmessage
$CMD_PERL ./imapsync \
--host1 $HOST1 --user1 tata \
--passfile1 ../../var/pass/secret.tata \
--host2 $HOST2 --user2 titi \
--passfile2 ../../var/pass/secret.titi \
--maxsize 10
--maxsize 10 --nofoldersizes --folder INBOX
}
ll_maxsize_useuid()
{
can_send && sendtestmessage
$CMD_PERL ./imapsync \
--host1 $HOST1 --user1 tata \
--passfile1 ../../var/pass/secret.tata \
--host2 $HOST2 --user2 titi \
--passfile2 ../../var/pass/secret.titi \
--maxsize 10 --nofoldersizes --folder INBOX \
--useuid
}
ll_skipsize()
{
@ -1159,6 +1210,16 @@ ll_delete() {
}
ll_delete_delete2() {
$CMD_PERL ./imapsync \
--host1 $HOST1 --user1 titi \
--passfile1 ../../var/pass/secret.titi \
--host2 $HOST2 --user2 tata \
--passfile2 ../../var/pass/secret.tata \
--delete --delete2
}
ll_bigmail() {
$CMD_PERL ./imapsync \
--host1 $HOST1 --user1 big1 \
@ -1550,6 +1611,16 @@ ll_useuid_nousecache()
# specific tests
##########################
Giancarlo_1() {
$CMD_PERL ./imapsync \
--host1 87.241.29.226 --user1 "Diego@studiobdp.local" \
--passfile1 ../../var/pass/secret.Giancarlo \
--host2 $HOST1 --user2 tata \
--passfile2 ../../var/pass/secret.tata \
--regextrans2 's/.*/INBOX.Giancarlo/' \
--nofoldersizes --useuid
}
godaddy_1_justlogin() {
$CMD_PERL ./imapsync \
--host1 $HOST1 --user1 tata \
@ -1566,7 +1637,7 @@ mailenable_1() {
--host2 email.avonvalley.wilts.sch.uk --user2 "GLamiral" \
--passfile2 ../../var/pass/secret.avonvalley \
--sep2 / --prefix2 '' --useuid \
--folder INBOX.Junk --folder INBOX.few_emails \
--folder INBOX --folder INBOX.Junk --folder INBOX.few_emails \
--delete2 --expunge2
}
@ -1594,6 +1665,34 @@ mailenable_3_reverse() {
mailenable_21_host1() {
$CMD_PERL ./imapsync \
--host1 elix-irr.com --user1 "greg.watson" \
--passfile1 ../../var/pass/secret.greg.watson \
--host2 $HOST1 --user2 zzz \
--passfile2 ../../var/pass/secret.zzz \
--sep1 / --prefix1 '' \
--delete2 --expunge2 --useuid
}
mailenable_22_host2() {
$CMD_PERL ./imapsync \
--host1 $HOST1 --user1 tata \
--passfile1 ../../var/pass/secret.tata \
--host2 elix-irr.com --user2 "greg.watson" \
--passfile2 ../../var/pass/secret.greg.watson \
--sep2 / --prefix2 '' \
--folder INBOX.Junk --folder INBOX --folder INBOX.few_emails \
--useuid --debugLIST
}
bug_zero_byte() {
$CMD_PERL ./imapsync \
--host1 buzon.us.es --user1 rafaeltovar \
@ -1630,8 +1729,6 @@ exchange_3_delete2() {
--folder INBOX.Junk --useuid --delete2
}
jong_1() {
$CMD_PERL ./imapsync \
--host1 mail.y-publicaties.nl --user1 gillesl --passfile1 ../../var/pass/secret.jong \
@ -1854,7 +1951,7 @@ dprof_bigmail()
# Tests list
mandatory_tests='
no_args
no_args
option_version
option_tests
option_tests_debug
@ -1922,6 +2019,7 @@ ll_authmech_PLAIN
ll_authmech_LOGIN
ll_authmech_CRAMMD5
ll_authuser
ll_delete_delete2
ll_delete2
ll_delete
ll_folderrec
@ -1936,6 +2034,8 @@ ll_nousecache
ll_delete2foldersonly
ll_delete2foldersonly_tmp
ll_delete2foldersbutnot
ll_folder_create
ll_folder_create_INBOX_Inbox
ll_delete2folders
ll_useuid
ll_useuid_nousecache

View File

@ -1,116 +0,0 @@
#!/usr/bin/env ruby
require 'net/imap'
#
# http://wonko.com/article/554
#
# Gilles LAMIRAL: Your Ruby code is nice. Is it GPL? Can I make a reference
# to it in the imapsync distribution?
#
# Wonko : Please consider this code public domain (and unsupported).
# You're more than welcome to refer to it if you'd like.
#
#
# Source server connection info.
SOURCE_HOST = 'mail.example.com'
SOURCE_PORT = 143
SOURCE_SSL = false
SOURCE_USER = 'username'
SOURCE_PASS = 'password'
# Destination server connection info.
DEST_HOST = 'imap.gmail.com'
DEST_PORT = 993
DEST_SSL = true
DEST_USER = 'username@gmail.com'
DEST_PASS = 'password'
# Mapping of source folders to destination folders. The key is the name of the
# folder on the source server, the value is the name on the destination server.
# Any folder not specified here will be ignored. If a destination folder does
# not exist, it will be created.
FOLDERS = {
'INBOX' => 'INBOX',
'sourcefolder' => 'gmailfolder'
}
# Utility methods.
def dd(message)
puts "[#{DEST_HOST}] #{message}"
end
def ds(message)
puts "[#{SOURCE_HOST}] #{message}"
end
# Connect and log into both servers.
ds 'connecting...'
source = Net::IMAP.new(SOURCE_HOST, SOURCE_PORT, SOURCE_SSL)
ds 'logging in...'
source.login(SOURCE_USER, SOURCE_PASS)
dd 'connecting...'
dest = Net::IMAP.new(DEST_HOST, DEST_PORT, DEST_SSL)
dd 'logging in...'
dest.login(DEST_USER, DEST_PASS)
# Loop through folders and copy messages.
FOLDERS.each do |source_folder, dest_folder|
# Open source folder in read-only mode.
begin
ds "selecting folder '#{source_folder}'..."
source.examine(source_folder)
rescue => e
ds "error: select failed: #{e}"
next
end
# Open (or create) destination folder in read-write mode.
begin
dd "selecting folder '#{dest_folder}'..."
dest.select(dest_folder)
rescue => e
begin
dd "folder not found; creating..."
dest.create(dest_folder)
dest.select(dest_folder)
rescue => ee
dd "error: could not create folder: #{e}"
next
end
end
# Build a lookup hash of all message ids present in the destination folder.
dest_info = {}
dd 'analyzing existing messages...'
dest.uid_fetch(dest.uid_search(['ALL']), ['ENVELOPE']).each do |data|
dest_info[data.attr['ENVELOPE'].message_id] = true
end
# Loop through all messages in the source folder.
source.uid_fetch(source.uid_search(['ALL']), ['ENVELOPE']).each do |data|
mid = data.attr['ENVELOPE'].message_id
# If this message is already in the destination folder, skip it.
next if dest_info[mid]
# Download the full message body from the source folder.
ds "downloading message #{mid}..."
msg = source.uid_fetch(data.attr['UID'], ['RFC822', 'FLAGS',
'INTERNALDATE']).first
# Append the message to the destination folder, preserving flags and
# internal timestamp.
dd "storing message #{mid}..."
dest.append(dest_folder, msg.attr['RFC822'], msg.attr['FLAGS'],
msg.attr['INTERNALDATE'])
end
source.close
dest.close
end
puts 'done'