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

« back to all changes in this revision

Viewing changes to kmailcvt/filter_sylpheed.cxx

  • 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_sylpheed.hxx  -  Sylpheed maildir mail import
3
 
                             -------------------
4
 
    begin                : April 07 2005
5
 
   copyright            : (C) 2005 by Danny Kukawka
6
 
   email                : danny.kukawka@web.de
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_sylpheed.hxx"
19
 
 
20
 
#include <klocale.h>
21
 
#include <kfiledialog.h>
22
 
#include <kdebug.h>
23
 
 
24
 
/** Default constructor. */
25
 
FilterSylpheed::FilterSylpheed( void ) :
26
 
        Filter( i18n( "Import Sylpheed Maildirs and Folder Structure" ),
27
 
                "Danny Kukawka",
28
 
                i18n( "<p><b>Sylpheed import filter</b></p>"
29
 
                      "<p>Select the base directory of the Sylpheed mailfolder you want to import "
30
 
                      "(usually: ~/Mail ).</p>"
31
 
                      "<p>Since it is possible to recreate the folder structure, the folders "
32
 
                      "will be stored under: \"Sylpheed-Import\" in your local folder.</p>"
33
 
                      "<p>This filter also recreates the status of message, e.g. new or forwarded.</p>") )
34
 
{}
35
 
 
36
 
/** Destructor. */
37
 
FilterSylpheed::~FilterSylpheed( void )
38
 
{
39
 
}
40
 
 
41
 
/** Recursive import of Sylpheed maildir. */
42
 
void FilterSylpheed::import( FilterInfo *info )
43
 
{
44
 
 
45
 
    QString _homeDir = QDir::homePath();
46
 
 
47
 
    KFileDialog *kfd = new KFileDialog( _homeDir, "", 0 );
48
 
    kfd->setMode( KFile::Directory | KFile::LocalOnly );
49
 
    kfd->exec();
50
 
    mailDir = kfd->selectedFile();
51
 
 
52
 
    if ( mailDir.isEmpty() ) {
53
 
        info->alert( i18n( "No directory selected." ) );
54
 
    }
55
 
    /**
56
 
     * If the user only select homedir no import needed because
57
 
     * there should be no files and we surely import wrong files.
58
 
     */
59
 
    else if ( mailDir == QDir::homePath() || mailDir == ( QDir::homePath() + '/' ) ) {
60
 
        info->addLog( i18n( "No files found for import." ) );
61
 
    } else {
62
 
        info->setOverall(0);
63
 
 
64
 
        /** Recursive import of the MailFolders */
65
 
        QDir dir(mailDir);
66
 
        const QStringList rootSubDirs = dir.entryList(QStringList("[^\\.]*"), QDir::Dirs , QDir::Name);
67
 
        int currentDir = 1, numSubDirs = rootSubDirs.size();
68
 
        QStringList::ConstIterator end = rootSubDirs.constEnd();
69
 
        for(QStringList::ConstIterator filename = rootSubDirs.constBegin() ; filename != end; ++filename, ++currentDir) {
70
 
            if(info->shouldTerminate()) break;
71
 
            importDirContents(info, dir.filePath(*filename));
72
 
            info->setOverall((int) ((float) currentDir / numSubDirs * 100));
73
 
        }
74
 
    }
75
 
 
76
 
    info->addLog( i18n("Finished importing emails from %1", mailDir ));
77
 
    if (count_duplicates > 0) {
78
 
        info->addLog( i18np("1 duplicate message not imported", "%1 duplicate messages not imported", count_duplicates));
79
 
    }
80
 
    if (info->shouldTerminate()) info->addLog( i18n("Finished import, canceled by user."));
81
 
    count_duplicates = 0;
82
 
    info->setCurrent(100);
83
 
    info->setOverall(100);
84
 
    delete kfd;
85
 
}
86
 
 
87
 
/**
88
 
 * Import of a directory contents.
89
 
 * @param info Information storage for the operation.
90
 
 * @param dirName The name of the directory to import.
91
 
 */
92
 
void FilterSylpheed::importDirContents( FilterInfo *info, const QString& dirName)
93
 
{
94
 
    if(info->shouldTerminate()) return;
95
 
 
96
 
    /** Here Import all archives in the current dir */
97
 
    importFiles(info, dirName);
98
 
 
99
 
    /** If there are subfolders, we import them one by one */
100
 
    QDir subfolders(dirName);
101
 
    const QStringList subDirs = subfolders.entryList(QStringList("[^\\.]*"), QDir::Dirs , QDir::Name);
102
 
    for(QStringList::ConstIterator filename = subDirs.constBegin() ; filename != subDirs.constEnd() ; ++filename) {
103
 
        if(info->shouldTerminate()) return;
104
 
        importDirContents(info, subfolders.filePath(*filename));
105
 
    }
106
 
}
107
 
 
108
 
 
109
 
/**
110
 
 * Import the files within a Folder.
111
 
 * @param info Information storage for the operation.
112
 
 * @param dirName The name of the directory to import.
113
 
 */
114
 
void FilterSylpheed::importFiles( FilterInfo *info, const QString& dirName)
115
 
{
116
 
    QDir dir(dirName);
117
 
    QString _path;
118
 
    bool generatedPath = false;
119
 
 
120
 
    QHash<QString,unsigned long> msgflags;
121
 
 
122
 
    QDir importDir (dirName);
123
 
    const QStringList files = importDir.entryList(QStringList("[^\\.]*"), QDir::Files, QDir::Name);
124
 
    int currentFile = 1, numFiles = files.size();
125
 
 
126
 
    readMarkFile(info, dir.filePath(".sylpheed_mark"), msgflags);
127
 
 
128
 
    for ( QStringList::ConstIterator mailFile = files.constBegin(); mailFile != files.constEnd(); ++mailFile, ++currentFile) {
129
 
        if(info->shouldTerminate()) return;
130
 
        QString _mfile = *mailFile;
131
 
        if (!(_mfile.endsWith(QLatin1String(".sylpheed_cache")) || _mfile.endsWith(QLatin1String(".sylpheed_mark"))
132
 
                    || _mfile.endsWith(QLatin1String(".mh_sequences")) )) {
133
 
            if(!generatedPath) {
134
 
                _path = "Sylpheed-Import/";
135
 
                QString _tmp = dir.filePath(*mailFile);
136
 
                _tmp = _tmp.remove(_tmp.length() - _mfile.length() -1, _mfile.length()+1);
137
 
                _path += _tmp.remove( mailDir, Qt::CaseSensitive );
138
 
                QString _info = _path;
139
 
                info->addLog(i18n("Import folder %1...", _info.remove(0,15)));
140
 
 
141
 
                info->setFrom(_info);
142
 
                info->setTo(_path);
143
 
                generatedPath = true;
144
 
            }
145
 
 
146
 
            QString flags;
147
 
            if (msgflags[_mfile])
148
 
                flags = msgFlagsToString((msgflags[_mfile]));
149
 
 
150
 
            if(info->removeDupMsg) {
151
 
                if(! addMessage( info, _path, dir.filePath(*mailFile), flags )) {
152
 
                    info->addLog( i18n("Could not import %1", *mailFile ) );
153
 
                }
154
 
                info->setCurrent((int) ((float) currentFile / numFiles * 100));
155
 
            } else {
156
 
                if(! addMessage_fastImport( info, _path, dir.filePath(*mailFile), flags )) {
157
 
                    info->addLog( i18n("Could not import %1", *mailFile ) );
158
 
                }
159
 
                info->setCurrent((int) ((float) currentFile / numFiles * 100));
160
 
            }
161
 
        }
162
 
    }
163
 
}
164
 
 
165
 
 
166
 
void FilterSylpheed::readMarkFile( FilterInfo *info, const QString &path, QHash<QString,unsigned long> &dict )
167
 
{
168
 
    /* Each sylpheed mail directory contains a .sylpheed_mark file which
169
 
     * contains all the flags for each messages. The layout of this file
170
 
     * is documented in the source code of sylpheed: in procmsg.h for
171
 
     * the flag bits, and procmsg.c.
172
 
     *
173
 
     * Note that the mark file stores 32 bit unsigned integers in the
174
 
     * platform's native "endianness".
175
 
     *
176
 
     * The mark file starts with a 32 bit unsigned integer with a version
177
 
     * number. It is then followed by pairs of 32 bit unsigned integers,
178
 
     * the first one with the message file name (which is a number),
179
 
     * and the second one with the actual message flags */
180
 
 
181
 
    quint32 in, flags;
182
 
    QFile file(path);
183
 
 
184
 
    if (!file.open(QIODevice::ReadOnly))
185
 
        return;
186
 
 
187
 
    QDataStream stream(&file);
188
 
 
189
 
    if (Q_BYTE_ORDER == Q_LITTLE_ENDIAN)
190
 
        stream.setByteOrder(QDataStream::LittleEndian);
191
 
 
192
 
 
193
 
 
194
 
    /* Read version; if the value is reasonably too big, we're looking
195
 
     * at a file created on another platform. I don't have any test
196
 
     * marks/folders, so just ignoring this case */
197
 
    stream >> in;
198
 
    if (in > (quint32) 0xffff)
199
 
        return;
200
 
 
201
 
    while (!stream.atEnd()) {
202
 
        if(info->shouldTerminate()){
203
 
            file.close();
204
 
            return;
205
 
        }
206
 
        stream >> in;
207
 
        stream >> flags;
208
 
        QString s;
209
 
        s.setNum((uint) in);
210
 
        dict.insert(s, flags);
211
 
    }
212
 
}
213
 
 
214
 
QString FilterSylpheed::msgFlagsToString(unsigned long flags)
215
 
{
216
 
    QString status;
217
 
 
218
 
    /* see sylpheed's procmsg.h */
219
 
    if (flags & 1UL) status += 'N';
220
 
    if (flags & 2UL) status += 'U';
221
 
    if ((flags & 3UL) == 0UL) status += 'R';
222
 
    if (flags & 8UL) status += 'D';
223
 
    if (flags & 16UL) status += 'A';
224
 
    if (flags & 32UL) status += 'F';
225
 
 
226
 
    return status;
227
 
}