~ubuntu-branches/ubuntu/raring/kdepim/raring-proposed

« back to all changes in this revision

Viewing changes to mailimporter/filter_evolution_v2.cpp

  • Committer: Package Import Robot
  • Author(s): Jonathan Riddell
  • Date: 2012-06-07 07:56:38 UTC
  • mfrom: (0.2.27)
  • Revision ID: package-import@ubuntu.com-20120607075638-0luhdq11z7sgvs4m
Tags: 4:4.8.80-0ubuntu1
New upstream release

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/***************************************************************************
 
2
            filter_evolution_v2.cxx  -  Evolution 2.0.x mail import
 
3
                             -------------------
 
4
    begin                : Januar 26 2005
 
5
    copyright            : (C) 2005 by Danny Kukawka <danny.kukawka@web.de>
 
6
                           (inspired and partly copied from filter_evolution)
 
7
 ***************************************************************************/
 
8
 
 
9
/***************************************************************************
 
10
 *                                                                         *
 
11
 *   This program is free software; you can redistribute it and/or modify  *
 
12
 *   it under the terms of the GNU General Public License as published by  *
 
13
 *   the Free Software Foundation; either version 2 of the License, or     *
 
14
 *   (at your option) any later version.                                   *
 
15
 *                                                                         *
 
16
 ***************************************************************************/
 
17
 
 
18
#include "filter_evolution_v2.h"
 
19
 
 
20
#include <klocale.h>
 
21
#include <kfiledialog.h>
 
22
#include <ktemporaryfile.h>
 
23
 
 
24
using namespace MailImporter;
 
25
 
 
26
/** Default constructor. */
 
27
FilterEvolution_v2::FilterEvolution_v2() :
 
28
  Filter(i18n("Import Evolution 2.x Local Mails and Folder Structure"),
 
29
         "Danny Kukawka",
 
30
         i18n("<p><b>Evolution 2.x import filter</b></p>"
 
31
              "<p>Select the base directory of your local Evolution mailfolder (usually ~/.evolution/mail/local/).</p>"
 
32
              "<p><b>Note:</b> Never choose a Folder which <u>does not</u> contain mbox-files (for example "
 
33
              "a maildir): if you do, you will get many new folders.</p>"
 
34
              "<p>Since it is possible to recreate the folder structure, the folders "
 
35
              "will be stored under: \"Evolution-Import\".</p>"))
 
36
{
 
37
}
 
38
 
 
39
/** Destructor. */
 
40
FilterEvolution_v2::~FilterEvolution_v2()
 
41
{
 
42
}
 
43
 
 
44
 
 
45
QString FilterEvolution_v2::defaultPath()
 
46
{
 
47
  return QDir::homePath() + QLatin1String( "/.evolution/mail/local" );
 
48
}
 
49
 
 
50
/** Recursive import of Evolution's mboxes. */
 
51
void FilterEvolution_v2::import()
 
52
{
 
53
  setCountDuplicates(0);
 
54
  /**
 
55
   * We ask the user to choose Evolution's root directory.
 
56
   * This should be usually ~/.evolution/mail/local/
 
57
   */
 
58
  QString evolDir = defaultPath();
 
59
  QDir d( evolDir );
 
60
  if ( !d.exists() ) {
 
61
    evolDir = QDir::homePath();
 
62
  }
 
63
 
 
64
  KFileDialog *kfd = new KFileDialog( evolDir, "", 0 );
 
65
  kfd->setMode(KFile::Directory | KFile::LocalOnly);
 
66
  kfd->exec();
 
67
  const QString dir = kfd->selectedFile();
 
68
  delete kfd;
 
69
  importMails( dir );
 
70
}
 
71
 
 
72
bool FilterEvolution_v2::excludeFiles(const QString& file)
 
73
{
 
74
  if (( file.endsWith(QLatin1String(".db")) ||
 
75
         file.endsWith(QLatin1String(".cmeta")) ||
 
76
         file.endsWith(QLatin1String(".ev-summary")) ||
 
77
         file.endsWith(QLatin1String(".ibex.index")) ||
 
78
         file.endsWith(QLatin1String(".ibex.index.data")) )) {
 
79
    return true;
 
80
  }
 
81
  return false;
 
82
}
 
83
 
 
84
void FilterEvolution_v2::importMails( const QString& maildir )
 
85
{
 
86
  setMailDir( maildir );
 
87
  if (mailDir().isEmpty()) {
 
88
    filterInfo()->alert(i18n("No directory selected."));
 
89
    return;
 
90
  }
 
91
  /**
 
92
   * If the user only select homedir no import needed because
 
93
   * there should be no files and we surely import wrong files.
 
94
   */
 
95
  else if ( mailDir() == QDir::homePath() || mailDir() == (QDir::homePath() + '/')) {
 
96
    filterInfo()->addErrorLogEntry(i18n("No files found for import."));
 
97
  } else {
 
98
    filterInfo()->setOverall(0);
 
99
 
 
100
    /** Recursive import of the MailArchives */
 
101
    QDir dir(mailDir());
 
102
    const QStringList rootSubDirs = dir.entryList(QStringList("[^\\.]*"), QDir::Dirs, QDir::Name); // Removal of . and ..
 
103
    int currentDir = 1, numSubDirs = rootSubDirs.size();
 
104
    QStringList::ConstIterator endFilename( rootSubDirs.constEnd() );
 
105
    for(QStringList::ConstIterator filename = rootSubDirs.constBegin() ; filename != endFilename ; ++filename, ++currentDir) {
 
106
      if (filterInfo()->shouldTerminate())
 
107
        break;
 
108
      importDirContents(dir.filePath(*filename), *filename, *filename);
 
109
      filterInfo()->setOverall((int) ((float) currentDir / numSubDirs * 100));
 
110
    }
 
111
 
 
112
    /** import last but not least all archives from the root-dir */
 
113
    QDir importDir (mailDir());
 
114
    const QStringList files = importDir.entryList(QStringList("[^\\.]*"), QDir::Files, QDir::Name);
 
115
    endFilename = files.constEnd();
 
116
    for ( QStringList::ConstIterator mailFile = files.constBegin(); mailFile != endFilename; ++mailFile) {
 
117
      if (filterInfo()->shouldTerminate())
 
118
        break;
 
119
      QString temp_mailfile = *mailFile;
 
120
      if (!excludeFiles(temp_mailfile) )
 
121
      {
 
122
        filterInfo()->addInfoLogEntry( i18n("Start import file %1...", temp_mailfile ) );
 
123
        importMBox(mailDir() + temp_mailfile , temp_mailfile, QString());
 
124
      }
 
125
    }
 
126
 
 
127
    filterInfo()->addInfoLogEntry( i18n("Finished importing emails from %1", mailDir() ));
 
128
    if(countDuplicates() > 0) {
 
129
      filterInfo()->addInfoLogEntry( i18np("1 duplicate message not imported", "%1 duplicate messages not imported", countDuplicates()));
 
130
    }
 
131
    if (filterInfo()->shouldTerminate())
 
132
      filterInfo()->addInfoLogEntry( i18n("Finished import, canceled by user."));
 
133
  }
 
134
  filterInfo()->setCurrent(100);
 
135
  filterInfo()->setOverall(100);
 
136
}
 
137
 
 
138
/**
 
139
 * Import of a directory contents.
 
140
 * @param info Information storage for the operation.
 
141
 * @param dirName The name of the directory to import.
 
142
 * @param KMailRootDir The directory's root directory in KMail's folder structure.
 
143
 * @param KMailSubDir The directory's direct ancestor in KMail's folder structure.
 
144
 */
 
145
void FilterEvolution_v2::importDirContents(const QString& dirName, const QString& KMailRootDir, const QString& KMailSubDir)
 
146
{
 
147
    if (filterInfo()->shouldTerminate()) return;
 
148
 
 
149
    /** Here Import all archives in the current dir */
 
150
    QDir dir(dirName);
 
151
 
 
152
    QDir importDir (dirName);
 
153
    const QStringList files = importDir.entryList(QStringList("[^\\.]*"), QDir::Files, QDir::Name);
 
154
    QStringList::ConstIterator mailFileEnd( files.constEnd() );
 
155
    for ( QStringList::ConstIterator mailFile = files.constBegin(); mailFile != mailFileEnd; ++mailFile) {
 
156
        QString temp_mailfile = *mailFile;
 
157
        if (!excludeFiles(temp_mailfile))
 
158
        {
 
159
          filterInfo()->addInfoLogEntry( i18n("Start import file %1...", temp_mailfile ) );
 
160
          importMBox((dirName + '/' + temp_mailfile) , KMailRootDir, KMailSubDir);
 
161
        }
 
162
    }
 
163
 
 
164
    /** If there are subfolders, we import them one by one */
 
165
    QDir subfolders(dirName);
 
166
    const QStringList subDirs = subfolders.entryList(QStringList("[^\\.]*"), QDir::Dirs, QDir::Name);
 
167
    QStringList::ConstIterator end( subDirs.constEnd() );
 
168
    for(QStringList::ConstIterator filename = subDirs.constBegin() ; filename != end; ++filename) {
 
169
        QString kSubDir;
 
170
        if(!KMailSubDir.isNull()) {
 
171
            kSubDir = KMailSubDir + '/' + *filename;
 
172
        } else {
 
173
            kSubDir = *filename;
 
174
        }
 
175
        importDirContents( subfolders.filePath(*filename), KMailRootDir, kSubDir);
 
176
    }
 
177
}
 
178
 
 
179
/**
 
180
 * Import of a MBox file.
 
181
 * @param info Information storage for the operation.
 
182
 * @param dirName The MBox's name.
 
183
 * @param KMailRootDir The directory's root directory in KMail's folder structure.
 
184
 * @param KMailSubDir The directory's equivalent in KMail's folder structure. *
 
185
 */
 
186
void FilterEvolution_v2::importMBox(const QString& mboxName, const QString& rootDir, const QString& targetDir)
 
187
{
 
188
  QFile mbox(mboxName);
 
189
  bool first_msg = true;
 
190
  if (!mbox.open(QIODevice::ReadOnly)) {
 
191
    filterInfo()->alert(i18n("Unable to open %1, skipping", mboxName));
 
192
  } else {
 
193
    QFileInfo filenameInfo(mboxName);
 
194
 
 
195
    filterInfo()->setCurrent(0);
 
196
    if( mboxName.length() > 20 ) {
 
197
      QString tmp_info = mboxName;
 
198
      tmp_info = tmp_info.replace( mailDir(), "../" );
 
199
      if (tmp_info.contains(".sbd"))
 
200
        tmp_info.remove(".sbd");
 
201
      filterInfo()->setFrom( tmp_info );
 
202
    } else
 
203
      filterInfo()->setFrom(mboxName);
 
204
        
 
205
    if(targetDir.contains(QLatin1String( ".sbd" ))) {
 
206
      QString tmp_info = targetDir;
 
207
      tmp_info.remove(QLatin1String( ".sbd" ));
 
208
      filterInfo()->setTo(tmp_info);
 
209
    } else
 
210
      filterInfo()->setTo(targetDir);
 
211
 
 
212
    QByteArray input(MAX_LINE, '\0');
 
213
    long l = 0;
 
214
 
 
215
    while (!mbox.atEnd()) {
 
216
      KTemporaryFile tmp;
 
217
      tmp.open();
 
218
      /** @todo check if the file is really a mbox, maybe search for 'from' string at start */
 
219
      /* comment by Danny:
 
220
       * Don't use QTextStream to read from mbox, better use QDataStream. QTextStream only
 
221
       * support Unicode/Latin1/Locale. So you lost information from emails with
 
222
       * charset!=Unicode/Latin1/Locale (e.g. KOI8-R) and Content-Transfer-Encoding != base64
 
223
       * (e.g. 8Bit). It also not help to convert the QTextStream to Unicode. By this you
 
224
       * get Unicode/UTF-email but KMail can't detect the correct charset.
 
225
       */
 
226
      QByteArray separate;
 
227
 
 
228
      if(!first_msg)
 
229
        tmp.write( input, l );
 
230
      l = mbox.readLine( input.data(),MAX_LINE); // read the first line, prevent "From "
 
231
      tmp.write( input, l );
 
232
 
 
233
      while ( ! mbox.atEnd() &&  (l = mbox.readLine(input.data(),MAX_LINE)) && ((separate = input.data()).left(5) != "From ")) {
 
234
        tmp.write( input, l );
 
235
      }
 
236
      tmp.flush();
 
237
      first_msg = false;
 
238
 
 
239
      QString destFolder;
 
240
      QString _targetDir = targetDir;
 
241
      if(!targetDir.isNull()) {
 
242
        if(_targetDir.contains(QLatin1String( ".sbd" )))
 
243
          _targetDir.remove(QLatin1String( ".sbd" ));
 
244
        destFolder += "Evolution-Import/" + _targetDir + '/' + filenameInfo.completeBaseName(); // mboxName;
 
245
      } else {
 
246
        destFolder = "Evolution-Import/" + rootDir;
 
247
        if(destFolder.contains(QLatin1String( ".sbd" )))
 
248
          destFolder.remove(QLatin1String( ".sbd" ));
 
249
      }
 
250
 
 
251
 
 
252
      if(filterInfo()->removeDupMessage())
 
253
        addMessage( destFolder, tmp.fileName() );
 
254
      else
 
255
        addMessage_fastImport( destFolder, tmp.fileName() );
 
256
 
 
257
      int currentPercentage = (int) (((float) mbox.pos() / filenameInfo.size()) * 100);
 
258
      filterInfo()->setCurrent(currentPercentage);
 
259
      if (filterInfo()->shouldTerminate())
 
260
        break;
 
261
    }
 
262
    mbox.close();
 
263
  }
 
264
}
 
265