attachmentfromfolderjob.cpp 5.78 KB
Newer Older
1
/*
Laurent Montel's avatar
Laurent Montel committed
2
    Copyright (C) 2011  Martin Bednár <serafean@gmail.com>
3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28

    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation; either version 2 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License along
    with this program; if not, write to the Free Software Foundation, Inc.,
    51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/

#include "attachmentfromfolderjob.h"

#include <KDebug>
#include <KLocalizedString>


#include <QtCore/QBuffer>
#include <QtCore/QDir>
#include <QtCore/QScopedPointer>

29
static const mode_t archivePerms = S_IFREG | 0644;
30 31 32 33 34 35

using namespace MessageCore;

class AttachmentFromFolderJob::Private
{

Laurent Montel's avatar
Laurent Montel committed
36
public:
37 38 39 40 41 42 43 44 45
    Private( AttachmentFromFolderJob *qq );

    void compressFolder();
    void addEntity( const QFileInfoList &f, const QString &path );

    AttachmentFromFolderJob *const q;
    KZip::Compression mCompression;
    AttachmentPart::Ptr mCompressedFolder;
    QScopedPointer<KZip> mZip;
46
    time_t mArchiveTime;
47 48 49
};

AttachmentFromFolderJob::Private::Private( AttachmentFromFolderJob* qq ) :
Laurent Montel's avatar
Laurent Montel committed
50 51 52 53
    q( qq ),
    mCompression( KZip::DeflateCompression ),
    mZip(0),
    mArchiveTime(QDateTime::currentDateTime().toTime_t())
54 55 56 57 58 59
{
}

void AttachmentFromFolderJob::Private::compressFolder()
{
    kDebug() << "starting compression";
60
    QString fileName = q->url().fileName();
61 62 63 64 65 66 67 68 69 70
    QByteArray array;
    QBuffer dev( &array );
    mZip.reset( new KZip( &dev ) );
    if ( !mZip->open( QIODevice::WriteOnly ) ) {
        q->setError( KJob::UserDefinedError );
        q->setErrorText( i18n( "Could not create compressed file." ) );
        q->emitResult();
        return;
    }
    mZip->setCompression( mCompression );
71 72 73
    mZip->writeDir( q->url().fileName(),QString(),QString(), 040755, mArchiveTime, mArchiveTime, mArchiveTime );
    kDebug() << "writing root directory : " << q->url().fileName();
    addEntity(  QDir( q->url().path() ).entryInfoList( QDir::Dirs | QDir::NoDotAndDotDot |
Laurent Montel's avatar
Laurent Montel committed
74
                                                   QDir::NoSymLinks | QDir::Files, QDir::DirsFirst ), fileName + QLatin1Char('/') );
75 76 77 78 79
    mZip->close();

    Q_ASSERT ( mCompressedFolder == 0 );

    mCompressedFolder = AttachmentPart::Ptr( new AttachmentPart );
80 81 82
    const QString newName = fileName + QLatin1String(".zip");
    mCompressedFolder->setName( newName );
    mCompressedFolder->setFileName( newName );
83
    mCompressedFolder->setMimeType( "application/zip" );
Laurent Montel's avatar
Laurent Montel committed
84
    //     mCompressedFolder->setCompressed( true );
85
    mCompressedFolder->setData( array );
Laurent Montel's avatar
Laurent Montel committed
86
    //     mCompressedFolder->setCompressible(false);
87 88 89 90 91 92 93 94 95
    q->setAttachmentPart( mCompressedFolder );
    q->emitResult();

    //TODO:add allowCompression bool to AttachmentPart && modify GUI to disable decompressing.
    //  Or leave attachment as uncompressed and let it be compressed again?
}

void AttachmentFromFolderJob::Private::addEntity( const QFileInfoList &f, const QString &path )
{
Laurent Montel's avatar
Laurent Montel committed
96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133
    foreach( const QFileInfo &info, f ){
        kDebug() << q->maximumAllowedSize() << "Attachment size : " << mZip->device()->size();

        if ( q->maximumAllowedSize() !=-1 && mZip->device()->size() > q->maximumAllowedSize() ) {
            q->setError( KJob::UserDefinedError );
            q->setErrorText( i18n
                             ( "The resulting attachment would be larger than the maximum allowed size, aborting." ) );
            q->emitResult();
            return;
        }

        if ( info.isDir() ) {
            kDebug() << "adding directory " << info.fileName() << "to zip";
            if ( !mZip->writeDir( path+info.fileName(), QString(), QString(), 040755, mArchiveTime, mArchiveTime, mArchiveTime ) ) {
                q->setError( KJob::UserDefinedError );
                q->setErrorText( i18n( "Could not add %1 to the archive", info.fileName() ) );
                q->emitResult();
            }
            addEntity( QDir( info.filePath() ).entryInfoList( QDir::Dirs | QDir::NoDotAndDotDot |
                                                              QDir::NoSymLinks | QDir::Files,QDir::DirsFirst ), path+info.fileName() + QLatin1Char('/'));
        }

        if ( info.isFile() ){
            kDebug() << "Adding file " << path+info.fileName() << "to zip";
            QFile file( info.filePath() );
            if ( !file.open( QIODevice::ReadOnly ) ) {
                q->setError( KJob::UserDefinedError );
                q->setErrorText( i18n( "Could not open %1 for reading.", file.fileName() ) );
                q->emitResult();
            }
            if ( !mZip->writeFile( path+info.fileName(), QString(),QString(),
                                   file.readAll().constData(),file.size(), archivePerms, mArchiveTime, mArchiveTime, mArchiveTime ) ) {
                q->setError( KJob::UserDefinedError );
                q->setErrorText( i18n( "Could not add %1 to the archive", file.fileName() ) );
                q->emitResult();
            }
            file.close();
        }
134 135 136 137 138
    }
}


AttachmentFromFolderJob::AttachmentFromFolderJob( const KUrl &url, QObject *parent ) :
Laurent Montel's avatar
Laurent Montel committed
139 140
    AttachmentFromUrlBaseJob ( url, parent ),
    d( new Private( this ) )
141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162
{
}

AttachmentFromFolderJob::~AttachmentFromFolderJob()
{
    delete d;
}

void AttachmentFromFolderJob::setCompression( KZip::Compression compression )
{
    d->mCompression = compression;
}

KZip::Compression AttachmentFromFolderJob::compression() const
{
    return d->mCompression;
}

void AttachmentFromFolderJob::doStart()
{
    d->compressFolder();
}
Laurent Montel's avatar
Laurent Montel committed
163