[prev in list] [next in list] [prev in thread] [next in thread] 

List:       kde-pim
Subject:    [Kde-pim] [PATCH] Fixing bug #38177 (leave on server for N days)
From:       Kristian Eide <kreide () online ! no>
Date:       2003-06-29 18:14:38
[Download RAW message or body]

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

Hi there!

I recently started using KMail, but I miss one feature available in other mail
readers: Leave mail on server for N days. This wish is registered as bug
#38177. I have now implemented this feature in KMail. This is actually my
first contribution to the KDE project, but hopefully not my last!

Some comments about my implementation: I have studied the source for KMail for
some time, and I see that the mail UIDs are stored simply as a list of
strings. To implement this feature the time the mail was first seen is also
needed; the simplest way to add this is to store it in a new list of ints
(seconds since epoch). To improve the UI (IMHO of course) I have changed the 
"Delete mail from server" option to "Leave message on server"; the change is 
only in the UI (it already is mLeaveOnServer in kmacctexppop.cpp) so no mail 
should be deleted accidentally from this. Now, when both the "leave message 
on server" and "delete from sever after N days" options are enabled KMail 
will check the age of each message on the server, and delete those which are 
too old.

Does this seem like an acceptable approach? If it is I hope my code can be
added to KMail. Unfortunately I only have very limited bandwidth to the
Internet at the moment, so haven't been able to check out the latest CVS
version of KDE; the patch is against KMail 1.5. I hope the patch can still be
applied without too many changes.

One more thing: I haven't been able to test this code extensively, so I would
appreciate anyone willing to test it and give me feedback.

- --
Kristian
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.2.2 (GNU/Linux)

iD8DBQE+/yyRRBuET7ul/ccRAhAkAJ0fRq0PyYzJrD38NJAbd6gb0LBu6ACdFOo6
o3grM4WVV7awrf1XSE7pV/0=
=ljKA
-----END PGP SIGNATURE-----

["delete-after-days.patch" (text/x-diff)]

diff -u ../../kdenetwork-3.1-orig/kmail/accountdialog.cpp ./accountdialog.cpp
--- ../../kdenetwork-3.1-orig/kmail/accountdialog.cpp	2002-12-05 21:49:11.000000000 \
                +0100
+++ ./accountdialog.cpp	2003-06-29 20:05:56.000000000 +0200
@@ -518,13 +518,34 @@
     new QCheckBox( i18n("Sto&re POP password in configuration file"), page1 );
   grid->addMultiCellWidget( mPop.storePasswordCheck, 6, 6, 0, 1 );
 
-  mPop.deleteMailCheck =
-    new QCheckBox( i18n("&Delete message from server after fetching"), page1 );
-  grid->addMultiCellWidget( mPop.deleteMailCheck, 7, 7, 0, 1 );
+  mPop.leaveMailCheck =
+    new QCheckBox( i18n("&Leave messages on server after fetching"), page1 );
+  grid->addMultiCellWidget( mPop.leaveMailCheck, 7, 7, 0, 1 );
+
+  QHBox * hboxDelete = new QHBox( page1 );
+  hboxDelete->setSpacing( KDialog::spacingHint() );
+  mPop.deleteAfterDaysCheck =
+    new QCheckBox( i18n("&Delete from server after"), hboxDelete );
+  mPop.deleteAfterDaysCheck->setEnabled( false );
+  connect( mPop.leaveMailCheck, SIGNAL(toggled(bool)),
+           mPop.deleteAfterDaysCheck, SLOT(setEnabled(bool)) );
+  mPop.deleteAfterDaysSpin = new KIntNumInput ( hboxDelete );
+  mPop.deleteAfterDaysSpin->setEnabled( false );
+  hboxDelete->setStretchFactor( mPop.deleteAfterDaysSpin, 1 );
+  mPop.deleteAfterDaysSpin->setRange( 1, 10000, 1, FALSE );
+  mPop.deleteAfterDaysSpin->setValue( 7 );
+  mPop.deleteAfterDaysSpin->setSuffix( i18n(" days") );
+  grid->addMultiCellWidget( hboxDelete, 8, 8, 0, 1 );
+  connect( mPop.deleteAfterDaysCheck, SIGNAL(toggled(bool)),
+           mPop.deleteAfterDaysSpin, SLOT(setEnabled(bool)) );
+  QString msgDelete = i18n("If you select this option, messages on the server "
+                           "will be automatically delete after this many days.");
+  QWhatsThis::add( mPop.deleteAfterDaysCheck, msgDelete );
+  QWhatsThis::add( mPop.deleteAfterDaysSpin, msgDelete );
 
   mPop.excludeCheck =
     new QCheckBox( i18n("E&xclude from \"Check Mail\""), page1 );
-  grid->addMultiCellWidget( mPop.excludeCheck, 8, 8, 0, 1 );
+  grid->addMultiCellWidget( mPop.excludeCheck, 9, 9, 0, 1 );
 
   QHBox * hbox = new QHBox( page1 );
   hbox->setSpacing( KDialog::spacingHint() );
@@ -536,40 +557,40 @@
   mPop.filterOnServerSizeSpin->setRange( 1, 10000000, 100, FALSE );
   mPop.filterOnServerSizeSpin->setValue( 50000 );
   mPop.filterOnServerSizeSpin->setSuffix( i18n(" byte") );
-  grid->addMultiCellWidget( hbox, 9, 9, 0, 1 );
+  grid->addMultiCellWidget( hbox, 10, 10, 0, 1 );
   connect( mPop.filterOnServerCheck, SIGNAL(toggled(bool)),
-	   mPop.filterOnServerSizeSpin, SLOT(setEnabled(bool)) );
+					 mPop.filterOnServerSizeSpin, SLOT(setEnabled(bool)) );
   QString msg = i18n("If you select this option, POP Filters will be used to "
-		     "decide what to do with messages. You can then select "
-		     "to download, delete or keep them on the server." );
+										 "decide what to do with messages. You can then select "
+										 "to download, delete or keep them on the server." );
   QWhatsThis::add( mPop.filterOnServerCheck, msg );
   QWhatsThis::add( mPop.filterOnServerSizeSpin, msg );
 
   mPop.intervalCheck =
     new QCheckBox( i18n("Enable &interval mail checking"), page1 );
-  grid->addMultiCellWidget( mPop.intervalCheck, 10, 10, 0, 1 );
+  grid->addMultiCellWidget( mPop.intervalCheck, 11, 11, 0, 1 );
   connect( mPop.intervalCheck, SIGNAL(toggled(bool)),
-	   this, SLOT(slotEnablePopInterval(bool)) );
+					 this, SLOT(slotEnablePopInterval(bool)) );
   mPop.intervalLabel = new QLabel( i18n("Check inter&val:"), page1 );
-  grid->addWidget( mPop.intervalLabel, 11, 0 );
+  grid->addWidget( mPop.intervalLabel, 12, 0 );
   mPop.intervalSpin = new KIntNumInput( page1 );
   mPop.intervalSpin->setRange( 1, 10000, 1, FALSE );
   mPop.intervalSpin->setSuffix( i18n(" min") );
   mPop.intervalSpin->setValue( 1 );
   mPop.intervalLabel->setBuddy( mPop.intervalSpin );
-  grid->addWidget( mPop.intervalSpin, 11, 1 );
+  grid->addWidget( mPop.intervalSpin, 12, 1 );
 
   label = new QLabel( i18n("Des&tination folder:"), page1 );
   grid->addWidget( label, 12, 0 );
   mPop.folderCombo = new QComboBox( false, page1 );
   label->setBuddy( mPop.folderCombo );
-  grid->addWidget( mPop.folderCombo, 12, 1 );
+  grid->addWidget( mPop.folderCombo, 13, 1 );
 
   label = new QLabel( i18n("Precom&mand:"), page1 );
   grid->addWidget( label, 13, 0 );
   mPop.precommand = new QLineEdit( page1 );
   label->setBuddy(mPop.precommand);
-  grid->addWidget( mPop.precommand, 13, 1 );
+  grid->addWidget( mPop.precommand, 14, 1 );
 
   QWidget *page2 = new QWidget( tabWidget );
   tabWidget->addTab( page2, i18n("&Extras") );
@@ -819,7 +840,9 @@
     mPop.portEdit->setText( QString("%1").arg( ap.port() ) );
     mPop.usePipeliningCheck->setChecked( ap.usePipelining() );
     mPop.storePasswordCheck->setChecked( ap.storePasswd() );
-    mPop.deleteMailCheck->setChecked( !ap.leaveOnServer() );
+    mPop.leaveMailCheck->setChecked( ap.leaveOnServer() );
+    mPop.deleteAfterDaysCheck->setChecked( ap.deleteAfterDays() >= 0 );
+    if (ap.deleteAfterDays() >= 0) mPop.deleteAfterDaysSpin->setValue( \
ap.deleteAfterDays() );  mPop.filterOnServerCheck->setChecked( ap.filterOnServer() );
     mPop.filterOnServerSizeSpin->setValue( ap.filterOnServerCheckSize() );
     mPop.intervalCheck->setChecked( interval >= 1 );
@@ -1115,7 +1138,8 @@
     epa.setUsePipelining( mPop.usePipeliningCheck->isChecked() );
     epa.setStorePasswd( mPop.storePasswordCheck->isChecked() );
     epa.setPasswd( mPop.passwordEdit->text(), epa.storePasswd() );
-    epa.setLeaveOnServer( !mPop.deleteMailCheck->isChecked() );
+    epa.setLeaveOnServer( mPop.leaveMailCheck->isChecked() );
+    if (mPop.deleteAfterDaysCheck->isChecked()) epa.setDeleteAfterDays( \
mPop.deleteAfterDaysSpin->value() );  epa.setFilterOnServer( \
                mPop.filterOnServerCheck->isChecked() );
     epa.setFilterOnServerCheckSize (mPop.filterOnServerSizeSpin->value() );
     epa.setPrecommand( mPop.precommand->text() );
diff -u ../../kdenetwork-3.1-orig/kmail/accountdialog.h ./accountdialog.h
--- ../../kdenetwork-3.1-orig/kmail/accountdialog.h	2002-12-05 21:49:11.000000000 \
                +0100
+++ ./accountdialog.h	2003-06-29 20:00:48.000000000 +0200
@@ -101,7 +101,9 @@
       QPushButton  *checkCapabilities;
       QCheckBox    *usePipeliningCheck;
       QCheckBox    *storePasswordCheck;
-      QCheckBox    *deleteMailCheck;
+      QCheckBox    *leaveMailCheck;
+      QCheckBox    *deleteAfterDaysCheck;
+      KIntNumInput *deleteAfterDaysSpin;
       QCheckBox    *retriveAllCheck;
       QCheckBox    *excludeCheck;
       QCheckBox    *intervalCheck;
diff -u ../../kdenetwork-3.1-orig/kmail/kmacctexppop.cpp ./kmacctexppop.cpp
--- ../../kdenetwork-3.1-orig/kmail/kmacctexppop.cpp	2002-12-05 21:49:12.000000000 \
                +0100
+++ ./kmacctexppop.cpp	2003-06-29 20:03:58.000000000 +0200
@@ -83,6 +83,7 @@
   mStorePasswd = FALSE;
   mAskAgain = FALSE;
   mLeaveOnServer = FALSE;
+  mDeleteAfterDays = -1;
   mFilterOnServer = FALSE;
   //tz todo
   mFilterOnServerCheckSize = 50000;
@@ -123,6 +124,7 @@
   setStorePasswd(acct->storePasswd());
   setPasswd(acct->passwd(), acct->storePasswd());
   setLeaveOnServer(acct->leaveOnServer());
+  setDeleteAfterDays(acct->deleteAfterDays());
   setFilterOnServer(acct->filterOnServer());
   setFilterOnServerCheckSize(acct->filterOnServerCheckSize());
   setPrecommand(acct->precommand());
@@ -151,11 +153,13 @@
     }
 
     QString seenUidList = locateLocal( "appdata", mLogin + ":" + "@" + mHost +
-				       ":" + QString("%1").arg(mPort) );
+																			 ":" + QString("%1").arg(mPort) );
     KConfig config( seenUidList );
     uidsOfSeenMsgs = config.readListEntry( "seenUidList" );
+    timeOfSeenMsgs = config.readIntListEntry( "seenUidTimeList" );
     headerLaterUids = config.readListEntry( "downloadLater" );
     uidsOfNextSeenMsgs.clear();
+    timeOfNextSeenMsgs.clear();
 
     interactive = _interactive;
     mUidlFinished = FALSE;
@@ -195,6 +199,7 @@
   mPort = config.readNumEntry("port");
   mProtocol = config.readNumEntry("protocol");
   mLeaveOnServer = config.readNumEntry("leave-on-server", FALSE);
+  mDeleteAfterDays = config.readNumEntry("delete-after-days", -1);
   mFilterOnServer = config.readNumEntry("filter-on-server", FALSE);
   mFilterOnServerCheckSize = config.readUnsignedNumEntry("filter-os-check-size", \
50000);  }
@@ -218,6 +223,7 @@
   config.writeEntry("port", static_cast<int>(mPort));
   config.writeEntry("protocol", mProtocol);
   config.writeEntry("leave-on-server", mLeaveOnServer);
+  config.writeEntry("delete-after-days", mDeleteAfterDays);
   config.writeEntry("filter-on-server", mFilterOnServer);
   config.writeEntry("filter-os-check-size", mFilterOnServerCheckSize);
 }
@@ -263,6 +269,13 @@
 }
 
 
+//-----------------------------------------------------------------------------
+void KMAcctExpPop::setDeleteAfterDays(int n)
+{
+  mDeleteAfterDays = n;
+}
+
+
 //---------------------------------------------------------------------------
 void KMAcctExpPop::setFilterOnServer(bool b)
 {
@@ -383,6 +396,7 @@
     else {
       idsOfMsgsToDelete.append( *curId );
       uidsOfNextSeenMsgs.append( *curUid );
+      timeOfNextSeenMsgs.append( QDateTime::currentDateTime().toTime_t() );
     }
     ++cur;
     ++curId;
@@ -668,6 +682,7 @@
         if (headersOnServer.current()->action() == Delete) {
           headerDeleteUids.append(headersOnServer.current()->uid());
           uidsOfNextSeenMsgs.append(headersOnServer.current()->uid());
+          timeOfNextSeenMsgs.append( QDateTime::currentDateTime().toTime_t() );
           idsOfMsgsToDelete.append(headersOnServer.current()->id());
         }
         else {
@@ -704,7 +719,25 @@
     kernel->folderMgr()->syncAllFolders();
 
     KURL url = getUrl();
-    if (mLeaveOnServer || idsOfMsgsToDelete.isEmpty()) {
+    if (mLeaveOnServer && mDeleteAfterDays >= 0 && !idsOfMsgsToDelete.isEmpty()) {
+      // Remove from idsOfMsgsToDelete entries which are newer than the limit
+      QDateTime timeLimit = QDateTime::currentDateTime();
+      timeLimit.addDays( -mDeleteAfterDays );
+      QStringList::Iterator cur = idsOfMsgsToDelete.begin();
+      while (cur != idsOfMsgsToDelete.end()) {
+        QDateTime msgTime;
+        msgTime.setTime_t( timeOfNextSeenMsgs[uidsOfNextSeenMsgs.findIndex(*cur)] );
+        
+        if (msgTime >= timeLimit) {
+          cur = idsOfMsgsToDelete.remove( cur );
+        }
+        else {
+          ++cur;
+        }
+      }
+    }
+    
+    if ((mLeaveOnServer && mDeleteAfterDays < 0) || idsOfMsgsToDelete.isEmpty()) {
       url.setPath(QString("/commit"));
       job = KIO::get(url, false, false );
     }
@@ -774,9 +807,10 @@
   // a new list from the server
   if (!mUidlFinished) return;
   QString seenUidList = locateLocal( "appdata", mLogin + ":" + "@" + mHost +
-				       ":" + QString("%1").arg(mPort) );
+																		 ":" + QString("%1").arg(mPort) );
   KConfig config( seenUidList );
   config.writeEntry( "seenUidList", uidsOfNextSeenMsgs );
+  config.writeEntry( "seenUidTimeList", timeOfNextSeenMsgs );
   config.writeEntry( "downloadLater", headerLaterUids );
   config.sync();
 }
@@ -891,9 +925,10 @@
         }
         else
           kdDebug(5006) << "KMAcctExpPop::slotData synchronization failure." << \
                endl;
-        if (uidsOfSeenMsgs.contains( uid ))
-          idsOfMsgsToDelete.append( id );
+
+        idsOfMsgsToDelete.append( id );
         uidsOfNextSeenMsgs.append( uid );
+        timeOfNextSeenMsgs.append( timeOfSeenMsgs[uidsOfSeenMsgs.findIndex(uid)] );
       }
     }
   }
diff -u ../../kdenetwork-3.1-orig/kmail/kmacctexppop.h ./kmacctexppop.h
--- ../../kdenetwork-3.1-orig/kmail/kmacctexppop.h	2002-12-05 21:49:12.000000000 \
                +0100
+++ ./kmacctexppop.h	2003-06-29 13:32:43.000000000 +0200
@@ -110,6 +110,12 @@
   virtual void setLeaveOnServer(bool);
 
   /**
+   * If value is positive, delete mail from server after that many days.
+   */
+  int deleteAfterDays(void) const { return mDeleteAfterDays; }
+  virtual void setDeleteAfterDays(int);
+
+  /**
    * Shall messages be filter on the server (TRUE)
    * or not (FALSE).
    */
@@ -170,6 +176,7 @@
   bool    mStorePasswd;
   bool    mAskAgain;
   bool    mLeaveOnServer;
+  int     mDeleteAfterDays;
   bool    gotMsgs;
   bool    mFilterOnServer;
   unsigned int mFilterOnServerCheckSize;
@@ -192,7 +199,9 @@
   QValueList<int> lensOfMsgs;
   QStringList uidsOfMsgs;
   QStringList uidsOfSeenMsgs; //UIDS of seen messages, saved in config
+  QValueList<int> timeOfSeenMsgs; //UIDS of seen messages, saved in config
   QStringList uidsOfNextSeenMsgs; //UIDS of new seen messages, for writing in the \
config file +  QValueList<int> timeOfNextSeenMsgs; //UIDS of new seen messages, for \
writing in the config file  QStringList idsOfMsgsToDelete;
   int indexOfCurrentMsg;
 



_______________________________________________
kde-pim mailing list
kde-pim@mail.kde.org
http://mail.kde.org/mailman/listinfo/kde-pim
kde-pim home page at http://pim.kde.org/


[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic