UBImportDocument.cpp 6.04 KB
Newer Older
Claudio Valerio's avatar
Claudio Valerio committed
1
/*
2
 * Copyright (C) 2015-2018 Département de l'Instruction Publique (DIP-SEM)
Craig Watson's avatar
Craig Watson committed
3
 *
Claudio Valerio's avatar
Claudio Valerio committed
4
 * Copyright (C) 2013 Open Education Foundation
Claudio Valerio's avatar
Claudio Valerio committed
5
 *
Claudio Valerio's avatar
Claudio Valerio committed
6 7
 * Copyright (C) 2010-2013 Groupement d'Intérêt Public pour
 * l'Education Numérique en Afrique (GIP ENA)
8
 *
Claudio Valerio's avatar
Claudio Valerio committed
9 10 11
 * This file is part of OpenBoard.
 *
 * OpenBoard is free software: you can redistribute it and/or modify
Claudio Valerio's avatar
Claudio Valerio committed
12 13
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, version 3 of the License,
14 15 16 17
 * with a specific linking exception for the OpenSSL project's
 * "OpenSSL" library (or with modified versions of it that use the
 * same license as the "OpenSSL" library).
 *
Claudio Valerio's avatar
Claudio Valerio committed
18
 * OpenBoard is distributed in the hope that it will be useful,
Claudio Valerio's avatar
Claudio Valerio committed
19
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
Claudio Valerio's avatar
Claudio Valerio committed
20
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
Claudio Valerio's avatar
Claudio Valerio committed
21
 * GNU General Public License for more details.
Claudio Valerio's avatar
Claudio Valerio committed
22
 *
Claudio Valerio's avatar
Claudio Valerio committed
23
 * You should have received a copy of the GNU General Public License
Claudio Valerio's avatar
Claudio Valerio committed
24
 * along with OpenBoard. If not, see <http://www.gnu.org/licenses/>.
Claudio Valerio's avatar
Claudio Valerio committed
25 26
 */

27

Claudio Valerio's avatar
Claudio Valerio committed
28

Claudio Valerio's avatar
Claudio Valerio committed
29

Claudio Valerio's avatar
Claudio Valerio committed
30 31 32 33 34 35 36 37 38
#include "UBImportDocument.h"
#include "document/UBDocumentProxy.h"

#include "frameworks/UBFileSystemUtils.h"

#include "core/UBApplication.h"
#include "core/UBSettings.h"
#include "core/UBPersistenceManager.h"

39 40 41
#include "globals/UBGlobals.h"

THIRD_PARTY_WARNINGS_DISABLE
42 43 44
#include "quazip.h"
#include "quazipfile.h"
#include "quazipfileinfo.h"
45
THIRD_PARTY_WARNINGS_ENABLE
Claudio Valerio's avatar
Claudio Valerio committed
46

47 48
#include "core/memcheck.h"

Claudio Valerio's avatar
Claudio Valerio committed
49
UBImportDocument::UBImportDocument(QObject *parent)
50
    :UBDocumentBasedImportAdaptor(parent)
Claudio Valerio's avatar
Claudio Valerio committed
51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68
{
    // NOOP
}

UBImportDocument::~UBImportDocument()
{
    // NOOP
}


QStringList UBImportDocument::supportedExtentions()
{
    return QStringList("ubz");
}


QString UBImportDocument::importFileFilter()
{
69
    return tr("OpenBoard (*.ubz)");
Claudio Valerio's avatar
Claudio Valerio committed
70 71 72
}


Anatoly Mihalchenko's avatar
Anatoly Mihalchenko committed
73
bool UBImportDocument::extractFileToDir(const QFile& pZipFile, const QString& pDir, QString& documentRoot)
Claudio Valerio's avatar
Claudio Valerio committed
74 75 76 77 78 79 80 81
{

    QDir rootDir(pDir);
    QuaZip zip(pZipFile.fileName());

    if(!zip.open(QuaZip::mdUnzip))
    {
        qWarning() << "Import failed. Cause zip.open(): " << zip.getZipError();
Anatoly Mihalchenko's avatar
Anatoly Mihalchenko committed
82
        return false;
Claudio Valerio's avatar
Claudio Valerio committed
83 84 85 86 87 88 89 90
    }

    zip.setFileNameCodec("UTF-8");
    QuaZipFileInfo info;
    QuaZipFile file(&zip);

    QFile out;
    char c;
Anatoly Mihalchenko's avatar
Anatoly Mihalchenko committed
91
    documentRoot = UBPersistenceManager::persistenceManager()->generateUniqueDocumentPath(pDir);
Claudio Valerio's avatar
Claudio Valerio committed
92 93 94 95 96 97
    for(bool more=zip.goToFirstFile(); more; more=zip.goToNextFile())
    {
        if(!zip.getCurrentFileInfo(&info))
        {
            //TOD UB 4.3 O display error to user or use crash reporter
            qWarning() << "Import failed. Cause: getCurrentFileInfo(): " << zip.getZipError();
Anatoly Mihalchenko's avatar
Anatoly Mihalchenko committed
98
            return false;
Claudio Valerio's avatar
Claudio Valerio committed
99 100 101 102 103
        }

        if(!file.open(QIODevice::ReadOnly))
        {
            qWarning() << "Import failed. Cause: file.open(): " << zip.getZipError();
Anatoly Mihalchenko's avatar
Anatoly Mihalchenko committed
104
            return false;
Claudio Valerio's avatar
Claudio Valerio committed
105 106 107 108 109
        }

        if(file.getZipError()!= UNZ_OK)
        {
            qWarning() << "Import failed. Cause: file.getFileName(): " << zip.getZipError();
Anatoly Mihalchenko's avatar
Anatoly Mihalchenko committed
110
            return false;
Claudio Valerio's avatar
Claudio Valerio committed
111 112
        }

Anatoly Mihalchenko's avatar
Anatoly Mihalchenko committed
113
        QString newFileName = documentRoot + "/" + file.getActualFileName();
Claudio Valerio's avatar
Claudio Valerio committed
114
        QFileInfo newFileInfo(newFileName);
Anatoly Mihalchenko's avatar
Anatoly Mihalchenko committed
115 116
        if (!rootDir.mkpath(newFileInfo.absolutePath()))
            return false;
Claudio Valerio's avatar
Claudio Valerio committed
117 118

        out.setFileName(newFileName);
Anatoly Mihalchenko's avatar
Anatoly Mihalchenko committed
119 120
        if (!out.open(QIODevice::WriteOnly))
            return false;
Claudio Valerio's avatar
Claudio Valerio committed
121 122 123 124 125 126 127 128 129

        // Slow like hell (on GNU/Linux at least), but it is not my fault.
        // Not ZIP/UNZIP package's fault either.
        // The slowest thing here is out.putChar(c).
        QByteArray outFileContent = file.readAll();
        if (out.write(outFileContent) == -1)
        {
            qWarning() << "Import failed. Cause: Unable to write file";
            out.close();
Anatoly Mihalchenko's avatar
Anatoly Mihalchenko committed
130
            return false;
Claudio Valerio's avatar
Claudio Valerio committed
131 132 133 134 135 136 137 138 139 140
        }

        while(file.getChar(&c))
            out.putChar(c);

        out.close();

        if(file.getZipError()!=UNZ_OK)
        {
            qWarning() << "Import failed. Cause: " << zip.getZipError();
Anatoly Mihalchenko's avatar
Anatoly Mihalchenko committed
141
            return false;
Claudio Valerio's avatar
Claudio Valerio committed
142 143 144 145 146
        }

        if(!file.atEnd())
        {
            qWarning() << "Import failed. Cause: read all but not EOF";
Anatoly Mihalchenko's avatar
Anatoly Mihalchenko committed
147
            return false;
Claudio Valerio's avatar
Claudio Valerio committed
148 149 150 151 152 153 154
        }

        file.close();

        if(file.getZipError()!=UNZ_OK)
        {
            qWarning() << "Import failed. Cause: file.close(): " <<  file.getZipError();
Anatoly Mihalchenko's avatar
Anatoly Mihalchenko committed
155
            return false;
Claudio Valerio's avatar
Claudio Valerio committed
156 157 158 159 160 161 162 163 164
        }

    }

    zip.close();

    if(zip.getZipError()!=UNZ_OK)
    {
      qWarning() << "Import failed. Cause: zip.close(): " << zip.getZipError();
Anatoly Mihalchenko's avatar
Anatoly Mihalchenko committed
165
      return false;
Claudio Valerio's avatar
Claudio Valerio committed
166 167
    }

Anatoly Mihalchenko's avatar
Anatoly Mihalchenko committed
168
    return true;
Claudio Valerio's avatar
Claudio Valerio committed
169 170 171 172 173 174 175 176 177 178
}

UBDocumentProxy* UBImportDocument::importFile(const QFile& pFile, const QString& pGroup)
{
    Q_UNUSED(pGroup); // group is defined in the imported file

    QFileInfo fi(pFile);
    UBApplication::showMessage(tr("Importing file %1...").arg(fi.baseName()), true);

    // first unzip the file to the correct place
179
    QString path = UBSettings::userDocumentDirectory();
Claudio Valerio's avatar
Claudio Valerio committed
180

Anatoly Mihalchenko's avatar
Anatoly Mihalchenko committed
181
    QString documentRootFolder;
182

Claudio Valerio's avatar
Claudio Valerio committed
183 184 185 186
    if(!extractFileToDir(pFile, path, documentRootFolder)){
        UBApplication::showMessage(tr("Import of file %1 failed.").arg(fi.baseName()));
        return NULL;
    }
Anatoly Mihalchenko's avatar
Anatoly Mihalchenko committed
187

188
    UBDocumentProxy* newDocument = UBPersistenceManager::persistenceManager()->createDocumentFromDir(documentRootFolder, pGroup, "", false, false, true);
Claudio Valerio's avatar
Claudio Valerio committed
189 190
    UBApplication::showMessage(tr("Import successful."));
    return newDocument;
Claudio Valerio's avatar
Claudio Valerio committed
191 192 193 194 195 196 197 198 199
}

bool UBImportDocument::addFileToDocument(UBDocumentProxy* pDocument, const QFile& pFile)
{
    QFileInfo fi(pFile);
    UBApplication::showMessage(tr("Importing file %1...").arg(fi.baseName()), true);

    QString path = UBFileSystemUtils::createTempDir();

Anatoly Mihalchenko's avatar
Anatoly Mihalchenko committed
200 201 202 203 204 205
    QString documentRootFolder;
    if (!extractFileToDir(pFile, path, documentRootFolder))
    {
        UBApplication::showMessage(tr("Import of file %1 failed.").arg(fi.baseName()));
        return false;
    }
206

Anatoly Mihalchenko's avatar
Anatoly Mihalchenko committed
207 208 209 210 211
    if (!UBPersistenceManager::persistenceManager()->addDirectoryContentToDocument(documentRootFolder, pDocument))
    {
        UBApplication::showMessage(tr("Import of file %1 failed.").arg(fi.baseName()));
        return false;
    }
Claudio Valerio's avatar
Claudio Valerio committed
212 213 214 215 216 217 218

    UBFileSystemUtils::deleteDir(path);

    UBApplication::showMessage(tr("Import successful."));

    return true;
}
219 220