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

mailcommon

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

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