19 #include "importjob.h"
22 #include "folderutil.h"
23 #include "kmfolderdir.h"
24 #include "kmfolderimap.h"
27 #include "progressmanager.h"
32 #include <tdelocale.h>
33 #include <tdemessagebox.h>
34 #include <kmimetype.h>
40 using namespace KMail;
42 KMail::ImportJob::ImportJob( TQWidget *parentWidget )
43 : TQObject( parentWidget ),
46 mParentWidget( parentWidget ),
47 mNumberOfImportedMessages( 0 ),
50 mCurrentMessageFile( 0 ),
56 KMail::ImportJob::~ImportJob()
58 if ( mArchive && mArchive->isOpened() ) {
65 void KMail::ImportJob::setFile(
const KURL &archiveFile )
67 mArchiveFile = archiveFile;
70 void KMail::ImportJob::setRootFolder(
KMFolder *rootFolder )
72 mRootFolder = rootFolder;
75 void KMail::ImportJob::finish()
77 kdDebug(5006) <<
"Finished import job." << endl;
78 mProgressItem->setComplete();
80 TQString text = i18n(
"Importing the archive file '%1' into the folder '%2' succeeded." )
81 .arg( mArchiveFile.path() ).arg( mRootFolder->name() );
82 text +=
"\n" + i18n(
"1 message was imported.",
"%n messages were imported.", mNumberOfImportedMessages );
83 KMessageBox::information( mParentWidget, text, i18n(
"Import finished." ) );
87 void KMail::ImportJob::cancelJob()
89 abort( i18n(
"The operation was canceled by the user." ) );
92 void KMail::ImportJob::abort(
const TQString &errorMessage )
98 TQString text = i18n(
"Failed to import the archive into folder '%1'." ).arg( mRootFolder->name() );
99 text +=
"\n" + errorMessage;
100 if ( mProgressItem ) {
101 mProgressItem->setComplete();
105 KMessageBox::sorry( mParentWidget, text, i18n(
"Importing archive failed." ) );
109 KMFolder * KMail::ImportJob::createSubFolder(
KMFolder *parent,
const TQString &folderName, mode_t permissions )
111 KMFolder *newFolder = FolderUtil::createSubFolder( parent, parent->
child(), folderName, TQString(),
112 KMFolderTypeMaildir );
114 abort( i18n(
"Unable to create subfolder for folder '%1'." ).arg( parent->name() ) );
121 chmod( newFolder->
location().latin1(), permissions | S_IXUSR );
122 chmod( newFolder->
subdirLocation().latin1(), permissions | S_IXUSR );
129 void KMail::ImportJob::enqueueMessages(
const KArchiveDirectory *dir,
KMFolder *folder )
131 const KArchiveDirectory *messageDir =
dynamic_cast<const KArchiveDirectory*
>( dir->entry(
"cur" ) );
133 Messages messagesToQueue;
134 messagesToQueue.parent = folder;
135 const TQStringList entries = messageDir->entries();
136 for ( uint i = 0; i < entries.size(); i++ ) {
137 const KArchiveEntry *entry = messageDir->entry( entries[i] );
139 if ( entry->isDirectory() ) {
140 kdWarning(5006) <<
"Unexpected subdirectory in archive folder " << dir->name() << endl;
143 kdDebug(5006) <<
"Queueing message " << entry->name() << endl;
144 const KArchiveFile *file =
static_cast<const KArchiveFile*
>( entry );
145 messagesToQueue.files.append( file );
148 mQueuedMessages.append( messagesToQueue );
151 kdWarning(5006) <<
"No 'cur' subdirectory for archive directory " << dir->name() << endl;
155 void KMail::ImportJob::messageAdded()
157 mNumberOfImportedMessages++;
158 if ( mCurrentFolder->folderType() == KMFolderTypeMaildir ||
159 mCurrentFolder->folderType() == KMFolderTypeCachedImap ) {
160 const TQString messageFile = mCurrentFolder->location() +
"/cur/" + mCurrentMessage->fileName();
162 if ( TQFile::exists( messageFile ) ) {
163 chmod( messageFile.latin1(), mCurrentMessageFile->permissions() );
170 kdWarning(5006) <<
"Unable to change permissions for newly created file: " << messageFile << endl;
176 mCurrentMessageFile = 0;
177 TQTimer::singleShot( 0,
this, TQ_SLOT( importNextMessage() ) );
180 void KMail::ImportJob::importNextMessage()
185 if ( mQueuedMessages.isEmpty() ) {
186 kdDebug(5006) <<
"importNextMessage(): Processed all messages in the queue." << endl;
187 if ( mCurrentFolder ) {
188 mCurrentFolder->close(
"ImportJob" );
191 importNextDirectory();
195 Messages &messages = mQueuedMessages.front();
196 if ( messages.files.isEmpty() ) {
197 mQueuedMessages.pop_front();
203 if ( folder != mCurrentFolder ) {
204 kdDebug(5006) <<
"importNextMessage(): Processed all messages in the current folder of the queue." << endl;
205 if ( mCurrentFolder ) {
206 mCurrentFolder->
close(
"ImportJob" );
208 mCurrentFolder = folder;
209 if ( mCurrentFolder->open(
"ImportJob" ) != 0 ) {
210 abort( i18n(
"Unable to open folder '%1'." ).arg( mCurrentFolder->name() ) );
213 kdDebug(5006) <<
"importNextMessage(): Current folder of queue is now: " << mCurrentFolder->name() << endl;
214 mProgressItem->setStatus( i18n(
"Importing folder %1" ).arg( mCurrentFolder->name() ) );
217 mProgressItem->setProgress( ( mProgressItem->progress() + 5 ) );
219 mCurrentMessageFile = messages.files.first();
220 Q_ASSERT( mCurrentMessageFile );
221 messages.files.removeFirst();
224 mCurrentMessage->fromByteArray( mCurrentMessageFile->data(),
true );
232 if ( mCurrentFolder->folderType() != KMFolderTypeImap ) {
233 if ( mCurrentFolder->addMsg( mCurrentMessage, &retIndex ) != 0 ) {
234 abort( i18n(
"Failed to add a message to the folder '%1'." ).arg( mCurrentFolder->name() ) );
240 ImapJob *imapJob =
new ImapJob( mCurrentMessage, ImapJob::tPutMessage,
241 dynamic_cast<KMFolderImap*
>( mCurrentFolder->storage() ) );
242 connect( imapJob, TQ_SIGNAL(result(KMail::FolderJob*)),
243 TQ_SLOT(messagePutResult(KMail::FolderJob*)) );
248 void KMail::ImportJob::messagePutResult( KMail::FolderJob *job )
253 if ( job->error() ) {
254 abort( i18n(
"Failed to upload a message to the IMAP server." ) );
258 KMFolderImap *imap =
dynamic_cast<KMFolderImap*
>( mCurrentFolder->storage() );
263 imap->addMsgQuiet( mCurrentMessage );
271 static TQString folderNameForDirectoryName(
const TQString &dirName )
273 Q_ASSERT( dirName.startsWith(
"." ) );
274 const TQString end =
".directory";
275 const int expectedIndex = dirName.length() - end.length();
276 if ( dirName.lower().find( end ) != expectedIndex )
278 TQString returnName = dirName.left( dirName.length() - end.length() );
279 returnName = returnName.right( returnName.length() - 1 );
283 KMFolder* KMail::ImportJob::getOrCreateSubFolder(
KMFolder *parentFolder,
const TQString &subFolderName,
284 mode_t subFolderPermissions )
287 abort( i18n(
"Unable to create subfolder for folder '%1'." ).arg( parentFolder->name() ) );
295 subFolder = createSubFolder( parentFolder, subFolderName, subFolderPermissions );
300 void KMail::ImportJob::importNextDirectory()
305 if ( mQueuedDirectories.isEmpty() ) {
310 Folder folder = mQueuedDirectories.first();
311 KMFolder *currentFolder = folder.parent;
312 mQueuedDirectories.pop_front();
313 kdDebug(5006) <<
"importNextDirectory(): Working on directory " << folder.archiveDir->name() << endl;
315 TQStringList entries = folder.archiveDir->entries();
316 for ( uint i = 0; i < entries.size(); i++ ) {
317 const KArchiveEntry *entry = folder.archiveDir->entry( entries[i] );
319 kdDebug(5006) <<
"Queueing entry " << entry->name() << endl;
320 if ( entry->isDirectory() ) {
321 const KArchiveDirectory *dir =
static_cast<const KArchiveDirectory*
>( entry );
322 if ( !dir->name().startsWith(
"." ) ) {
324 kdDebug(5006) <<
"Queueing messages in folder " << entry->name() << endl;
325 KMFolder *subFolder = getOrCreateSubFolder( currentFolder, entry->name(), entry->permissions() );
329 enqueueMessages( dir, subFolder );
335 const TQString folderName = folderNameForDirectoryName( entry->name() );
336 if ( folderName.isEmpty() ) {
337 abort( i18n(
"Unexpected subdirectory named '%1'." ).arg( entry->name() ) );
340 KMFolder *subFolder = getOrCreateSubFolder( currentFolder, folderName, entry->permissions() );
345 newFolder.archiveDir = dir;
346 newFolder.parent = subFolder;
347 kdDebug(5006) <<
"Enqueueing directory " << entry->name() << endl;
348 mQueuedDirectories.push_back( newFolder );
360 void KMail::ImportJob::start()
362 Q_ASSERT( mRootFolder );
363 Q_ASSERT( mArchiveFile.isValid() );
365 KMimeType::Ptr mimeType = KMimeType::findByURL( mArchiveFile, 0,
true );
366 if ( !mimeType->patterns().grep(
"tar",
false ).isEmpty() )
367 mArchive =
new KTar( mArchiveFile.path() );
368 else if ( !mimeType->patterns().grep(
"zip",
false ).isEmpty() )
369 mArchive =
new KZip( mArchiveFile.path() );
371 abort( i18n(
"The file '%1' does not appear to be a valid archive." ).arg( mArchiveFile.path() ) );
375 if ( !mArchive->open( IO_ReadOnly ) ) {
376 abort( i18n(
"Unable to open archive file '%1'" ).arg( mArchiveFile.path() ) );
380 mProgressItem = KPIM::ProgressManager::createProgressItem(
382 i18n(
"Importing Archive" ),
385 mProgressItem->setUsesBusyIndicator(
true );
386 connect( mProgressItem, TQ_SIGNAL(progressItemCanceled(KPIM::ProgressItem*)),
387 this, TQ_SLOT(cancelJob()) );
390 nextFolder.archiveDir = mArchive->directory();
391 nextFolder.parent = mRootFolder;
392 mQueuedDirectories.push_back( nextFolder );
393 importNextDirectory();
396 #include "importjob.moc"
virtual KMFolderNode * hasNamedFolder(const TQString &name)
Returns folder with given name or zero if it does not exist.
TQString subdirLocation() const
Returns full path to sub directory file.
KMFolderDir * child() const
Returns the folder directory associated with this node or 0 if no such directory exists.
void close(const char *owner, bool force=false)
Close folder.
KMFolderDir * createChildFolder()
Create a child folder directory and associates it with this folder.
TQString location() const
Returns full path to folder file.