• Skip to content
  • Skip to link menu
KDE API Reference
  • KDE API Reference
  • kdepim API Reference
  • KDE Home
  • Contact Us
 

mailcommon

  • sources
  • kde-4.14
  • kdepim
  • mailcommon
  • job
expirejob.cpp
Go to the documentation of this file.
1 
28 #include "expirejob.h"
29 #include "collectionpage/attributes/expirecollectionattribute.h"
30 #include "kernel/mailkernel.h"
31 #include "util/mailutil.h"
32 
33 #include <libkdepim/misc/broadcaststatus.h>
34 using KPIM::BroadcastStatus;
35 
36 #include <KDebug>
37 #include <KLocale>
38 
39 #include <Akonadi/ItemDeleteJob>
40 #include <Akonadi/ItemModifyJob>
41 #include <Akonadi/ItemFetchJob>
42 #include <Akonadi/ItemFetchScope>
43 #include <Akonadi/ItemMoveJob>
44 #include <Akonadi/KMime/MessageParts>
45 #include <Akonadi/KMime/MessageStatus>
46 #include <akonadi/kmime/messageflags.h>
47 #include <KMime/Message>
48 
49 /*
50  Testcases for folder expiry:
51  Automatic expiry:
52  - normal case (ensure folder has old mails and expiry settings, wait for auto-expiry)
53  - having the folder selected when the expiry job would run (gets delayed)
54  - selecting a folder while an expiry job is running for it (should interrupt)
55  - exiting kmail while an expiry job is running (should abort & delete things cleanly)
56  Manual expiry:
57  - RMB / expire (for one folder) [KMMainWidget::slotExpireFolder()]
58  - RMB on Local Folders / Expire All Folders [KMFolderMgr::expireAll()]
59  - Expire All Folders [KMMainWidget::slotExpireAll()]
60 */
61 
62 namespace MailCommon {
63 
64 ExpireJob::ExpireJob( const Akonadi::Collection &folder, bool immediate )
65  : ScheduledJob( folder, immediate ), mMaxUnreadTime( 0 ), mMaxReadTime( 0 ), mMoveToFolder( 0 )
66 {
67 }
68 
69 ExpireJob::~ExpireJob()
70 {
71  kDebug();
72 }
73 
74 void ExpireJob::kill()
75 {
76  ScheduledJob::kill();
77 }
78 
79 void ExpireJob::execute()
80 {
81  mMaxUnreadTime = 0;
82  mMaxReadTime = 0;
83  int unreadDays, readDays;
84  bool mustDeleteExpirationAttribute = false;
85 
86  MailCommon::ExpireCollectionAttribute *expirationAttribute =
87  MailCommon::Util::expirationCollectionAttribute(
88  mSrcFolder, mustDeleteExpirationAttribute );
89 
90  expirationAttribute->daysToExpire( unreadDays, readDays );
91  if ( mustDeleteExpirationAttribute ) {
92  delete expirationAttribute;
93  }
94 
95  if ( unreadDays > 0 ) {
96  kDebug() << "ExpireJob: deleting unread older than"<< unreadDays << "days";
97  mMaxUnreadTime = time(0) - unreadDays * 3600 * 24;
98  }
99  if ( readDays > 0 ) {
100  kDebug() << "ExpireJob: deleting read older than"<< readDays << "days";
101  mMaxReadTime = time(0) - readDays * 3600 * 24;
102  }
103 
104  if ( ( mMaxUnreadTime == 0 ) && ( mMaxReadTime == 0 ) ) {
105  kDebug() << "ExpireJob: nothing to do";
106  deleteLater();
107  return;
108  }
109  kDebug() << "ExpireJob: starting to expire in folder" << mSrcFolder.name();
110  slotDoWork();
111  // do nothing here, we might be deleted!
112 }
113 
114 void ExpireJob::slotDoWork()
115 {
116  Akonadi::ItemFetchJob *job = new Akonadi::ItemFetchJob( mSrcFolder, this );
117  job->fetchScope().fetchPayloadPart( Akonadi::MessagePart::Envelope );
118  connect( job, SIGNAL(result(KJob*)), SLOT(itemFetchResult(KJob*)) );
119 }
120 
121 void ExpireJob::itemFetchResult( KJob *job )
122 {
123  if ( job->error() ) {
124  kWarning() << job->errorString();
125  deleteLater();
126  return;
127  }
128 
129  foreach ( const Akonadi::Item &item, qobject_cast<Akonadi::ItemFetchJob*>( job )->items() ) {
130  if ( !item.hasPayload<KMime::Message::Ptr>() ) {
131  continue;
132  }
133 
134  const KMime::Message::Ptr mb = item.payload<KMime::Message::Ptr>();
135  Akonadi::MessageStatus status;
136  status.setStatusFromFlags( item.flags() );
137  if ( ( status.isImportant() || status.isToAct() || status.isWatched() ) &&
138  SettingsIf->excludeImportantMailFromExpiry() ) {
139  continue;
140  }
141 
142  time_t maxTime = status.isRead() ? mMaxReadTime : mMaxUnreadTime;
143 
144  if ( !mb->date( false ) ) {
145  continue;
146  }
147 
148  if ( mb->date()->dateTime().dateTime().toTime_t() < maxTime ) {
149  mRemovedMsgs.append( item );
150  }
151  }
152 
153  done();
154 }
155 
156 void ExpireJob::done()
157 {
158  QString str;
159  bool moving = false;
160 
161  if ( !mRemovedMsgs.isEmpty() ) {
162  int count = mRemovedMsgs.count();
163 
164  // The command shouldn't kill us because it opens the folder
165  mCancellable = false;
166  bool mustDeleteExpirationAttribute = false;
167 
168  MailCommon::ExpireCollectionAttribute *expirationAttribute =
169  MailCommon::Util::expirationCollectionAttribute(
170  mSrcFolder, mustDeleteExpirationAttribute );
171 
172  if ( expirationAttribute->expireAction() == MailCommon::ExpireCollectionAttribute::ExpireDelete ) {
173  // Expire by deletion, i.e. move to null target folder
174  kDebug() << "ExpireJob: finished expiring in folder"
175  << mSrcFolder.name()
176  << count << "messages to remove.";
177  Akonadi::ItemDeleteJob *job = new Akonadi::ItemDeleteJob( mRemovedMsgs, this );
178  connect( job, SIGNAL(result(KJob*)), this, SLOT(slotExpireDone(KJob*)) );
179  moving = true;
180  str = i18np( "Removing 1 old message from folder %2...",
181  "Removing %1 old messages from folder %2...",
182  count, mSrcFolder.name() );
183  } else {
184  // Expire by moving
185  mMoveToFolder = Kernel::self()->collectionFromId( expirationAttribute->expireToFolderId() );
186  if ( !mMoveToFolder.isValid() ) {
187  str = i18n( "Cannot expire messages from folder %1: destination "
188  "folder %2 not found",
189  mSrcFolder.name(), expirationAttribute->expireToFolderId() );
190  kWarning() << str;
191  } else {
192  kDebug() << "ExpireJob: finished expiring in folder"
193  << mSrcFolder.name()
194  << mRemovedMsgs.count() << "messages to move to"
195  << mMoveToFolder.name();
196  Akonadi::ItemMoveJob *job = new Akonadi::ItemMoveJob( mRemovedMsgs, mMoveToFolder, this );
197  connect( job, SIGNAL(result(KJob*)), this, SLOT(slotMoveDone(KJob*)) );
198  moving = true;
199  str = i18np( "Moving 1 old message from folder %2 to folder %3...",
200  "Moving %1 old messages from folder %2 to folder %3...",
201  count, mSrcFolder.name(), mMoveToFolder.name() );
202  }
203  }
204  if ( mustDeleteExpirationAttribute ) {
205  delete expirationAttribute;
206  }
207  }
208  if ( !str.isEmpty() ) {
209  BroadcastStatus::instance()->setStatusMsg( str );
210  }
211 
212  if ( !moving ) {
213  deleteLater();
214  }
215 }
216 
217 void ExpireJob::slotMoveDone( KJob *job )
218 {
219  if ( job->error() ) {
220  kError() << job->error() << job->errorString();
221  }
222  Akonadi::ItemMoveJob *itemjob = dynamic_cast<Akonadi::ItemMoveJob *>( job );
223  if ( itemjob ) {
224  QList<Akonadi::Item> lst = itemjob->items();
225  if ( !lst.isEmpty() ) {
226  QList<Akonadi::Item> newLst;
227  Q_FOREACH( Akonadi::Item item, lst ) {
228  if (!item.hasFlag(Akonadi::MessageFlags::Seen) ) {
229  item.setFlag( Akonadi::MessageFlags::Seen );
230  newLst<<item;
231  }
232  }
233  if ( !newLst.isEmpty() ) {
234  Akonadi::ItemModifyJob *modifyJob = new Akonadi::ItemModifyJob( newLst, this );
235  modifyJob->disableRevisionCheck();
236  connect( modifyJob, SIGNAL(result(KJob*)), this, SLOT(slotExpireDone(KJob*)) );
237  } else {
238  slotExpireDone( job );
239  }
240  }
241  } else {
242  slotExpireDone( job );
243  }
244 }
245 
246 void ExpireJob::slotExpireDone( KJob *job )
247 {
248  if ( job->error() ) {
249  kError() << job->error() << job->errorString();
250  }
251 
252  QString msg;
253  const int error = job->error();
254  bool mustDeleteExpirationAttribute = false;
255 
256  MailCommon::ExpireCollectionAttribute *expirationAttribute =
257  MailCommon::Util::expirationCollectionAttribute(
258  mSrcFolder, mustDeleteExpirationAttribute );
259 
260  switch ( error ) {
261  case KJob::NoError:
262  if ( expirationAttribute->expireAction() == MailCommon::ExpireCollectionAttribute::ExpireDelete ) {
263  msg = i18np( "Removed 1 old message from folder %2.",
264  "Removed %1 old messages from folder %2.",
265  mRemovedMsgs.count(),
266  mSrcFolder.name() );
267  } else {
268  msg = i18np( "Moved 1 old message from folder %2 to folder %3.",
269  "Moved %1 old messages from folder %2 to folder %3.",
270  mRemovedMsgs.count(), mSrcFolder.name(), mMoveToFolder.name() );
271  }
272  break;
273 
274  case Akonadi::Job::UserCanceled:
275  if ( expirationAttribute->expireAction() == MailCommon::ExpireCollectionAttribute::ExpireDelete ) {
276  msg = i18n( "Removing old messages from folder %1 was canceled.",
277  mSrcFolder.name() );
278  } else {
279  msg = i18n( "Moving old messages from folder %1 to folder %2 was "
280  "canceled.",
281  mSrcFolder.name(), mMoveToFolder.name() );
282  }
283  break;
284 
285  default: //any other error
286  if ( expirationAttribute->expireAction() == MailCommon::ExpireCollectionAttribute::ExpireDelete ) {
287  msg = i18n( "Removing old messages from folder %1 failed.",
288  mSrcFolder.name() );
289  } else {
290  msg = i18n( "Moving old messages from folder %1 to folder %2 failed.",
291  mSrcFolder.name(), mMoveToFolder.name() );
292  }
293  break;
294  }
295 
296  BroadcastStatus::instance()->setStatusMsg( msg );
297  if ( mustDeleteExpirationAttribute ) {
298  delete expirationAttribute;
299  }
300  deleteLater();
301 }
302 
303 }
304 
SettingsIf
#define SettingsIf
Definition: mailkernel.h:193
expirecollectionattribute.h
expirejob.h
MailCommon::ExpireJob::execute
virtual void execute()
Has to be reimplemented.
Definition: expirejob.cpp:79
MailCommon::Util::expirationCollectionAttribute
MAILCOMMON_EXPORT MailCommon::ExpireCollectionAttribute * expirationCollectionAttribute(const Akonadi::Collection &collection, bool &mustDeleteExpirationAttribute)
Definition: mailutil.cpp:458
MailCommon::ExpireCollectionAttribute
Definition: expirecollectionattribute.h:29
MailCommon::FolderJob::kill
virtual void kill()
Interrupt the job.
Definition: folderjob.cpp:60
MailCommon::FolderJob::mCancellable
bool mCancellable
Definition: folderjob.h:112
MailCommon::FolderJob::result
void result(FolderJob *job)
Emitted when the job finishes all processing.
QList::count
int count(const T &value) const
QList::append
void append(const T &value)
QList::isEmpty
bool isEmpty() const
QString::isEmpty
bool isEmpty() const
MailCommon::ExpireCollectionAttribute::expireAction
ExpireAction expireAction() const
What should expiry do? Delete or move to another folder?
Definition: expirecollectionattribute.cpp:110
MailCommon::ExpireJob::ExpireJob
ExpireJob(const Akonadi::Collection &folder, bool immediate)
Definition: expirejob.cpp:64
MailCommon::FolderJob::error
int error() const
Definition: folderjob.h:63
QObject::deleteLater
void deleteLater()
QString
QList< Akonadi::Item >
MailCommon::Kernel::collectionFromId
Akonadi::Collection collectionFromId(const Akonadi::Collection::Id &id) const
Returns the collection associated with the given id, or an invalid collection if not found...
Definition: mailkernel.cpp:83
MailCommon::ExpireJob::~ExpireJob
virtual ~ExpireJob()
Definition: expirejob.cpp:69
MailCommon::ExpireCollectionAttribute::ExpireDelete
Definition: expirecollectionattribute.h:48
mailkernel.h
MailCommon::ScheduledJob
Base class for scheduled jobs.
Definition: jobscheduler.h:137
MailCommon::FolderJob::mSrcFolder
Akonadi::Collection mSrcFolder
Definition: folderjob.h:108
MailCommon::ExpireCollectionAttribute::expireToFolderId
Akonadi::Collection::Id expireToFolderId() const
If expiry should move to folder, return the ID of that folder.
Definition: expirecollectionattribute.cpp:120
QObject::connect
bool connect(const QObject *sender, const char *signal, const QObject *receiver, const char *method, Qt::ConnectionType type)
MailCommon::Kernel::self
static Kernel * self()
Definition: mailkernel.cpp:73
mailutil.h
MailCommon::ExpireCollectionAttribute::daysToExpire
void daysToExpire(int &unreadDays, int &readDays)
Definition: expirecollectionattribute.cpp:163
MailCommon::ExpireJob::kill
virtual void kill()
Interrupt the job.
Definition: expirejob.cpp:74
This file is part of the KDE documentation.
Documentation copyright © 1996-2020 The KDE developers.
Generated on Mon Jun 22 2020 13:31:40 by doxygen 1.8.7 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.

mailcommon

Skip menu "mailcommon"
  • Main Page
  • Namespace List
  • Namespace Members
  • Alphabetical List
  • Class List
  • Class Hierarchy
  • Class Members
  • File List
  • File Members
  • Related Pages

kdepim API Reference

Skip menu "kdepim API Reference"
  • akonadi_next
  • akregator
  • blogilo
  • calendarsupport
  • console
  •   kabcclient
  •   konsolekalendar
  • kaddressbook
  • kalarm
  •   lib
  • kdgantt2
  • kjots
  • kleopatra
  • kmail
  • knode
  • knotes
  • kontact
  • korgac
  • korganizer
  • ktimetracker
  • libkdepim
  • libkleo
  • libkpgp
  • mailcommon
  • messagelist
  • messageviewer
  • pimprint

Search



Report problems with this website to our bug tracking system.
Contact the specific authors with questions and comments about the page contents.

KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. | Legal