You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
868 lines
26 KiB
868 lines
26 KiB
/* |
|
* Copyright (C) 2015-2018 Département de l'Instruction Publique (DIP-SEM) |
|
* |
|
* Copyright (C) 2013 Open Education Foundation |
|
* |
|
* Copyright (C) 2010-2013 Groupement d'Intérêt Public pour |
|
* l'Education Numérique en Afrique (GIP ENA) |
|
* |
|
* This file is part of OpenBoard. |
|
* |
|
* OpenBoard 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, version 3 of the License, |
|
* 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). |
|
* |
|
* OpenBoard 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 OpenBoard. If not, see <http://www.gnu.org/licenses/>. |
|
*/ |
|
|
|
|
|
|
|
|
|
#include "UBFileSystemUtils.h" |
|
|
|
#include <QtGui> |
|
|
|
#include "core/UBApplication.h" |
|
|
|
#include "globals/UBGlobals.h" |
|
|
|
THIRD_PARTY_WARNINGS_DISABLE |
|
#include "quazipfile.h" |
|
#include <openssl/md5.h> |
|
THIRD_PARTY_WARNINGS_ENABLE |
|
|
|
#include "core/memcheck.h" |
|
|
|
QStringList UBFileSystemUtils::sTempDirToCleanUp; |
|
|
|
|
|
UBFileSystemUtils::UBFileSystemUtils() |
|
{ |
|
// NOOP |
|
} |
|
|
|
|
|
UBFileSystemUtils::~UBFileSystemUtils() |
|
{ |
|
// NOOP |
|
} |
|
|
|
|
|
QString UBFileSystemUtils::removeLocalFilePrefix(QString input) |
|
{ |
|
#ifdef Q_OS_WIN |
|
if(input.startsWith("file:///")) |
|
return input.mid(8); |
|
else |
|
return input; |
|
#else |
|
if(input.startsWith("file://")) |
|
return input.mid(7); |
|
else |
|
return input; |
|
#endif |
|
} |
|
|
|
bool UBFileSystemUtils::isAZipFile(QString &filePath) |
|
{ |
|
if(QFileInfo(filePath).isDir()) return false; |
|
QFile file(filePath); |
|
if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) |
|
return false; |
|
|
|
bool result = false; |
|
QByteArray responseArray = file.readLine(10); |
|
QString responseString(responseArray); |
|
|
|
result = responseString.startsWith("pk", Qt::CaseInsensitive); |
|
|
|
file.close(); |
|
return result; |
|
} |
|
|
|
bool UBFileSystemUtils::copyFile(const QString &source, const QString &destination, bool overwrite) |
|
{ |
|
if (!QFile::exists(source)) { |
|
qDebug() << "file" << source << "does not present in fs"; |
|
return false; |
|
} |
|
|
|
QString normalizedDestination = destination; |
|
if (QFile::exists(normalizedDestination)) { |
|
if (QFileInfo(normalizedDestination).isFile() && overwrite) { |
|
QFile::remove(normalizedDestination); |
|
} |
|
} else { |
|
normalizedDestination = normalizedDestination.replace(QString("\\"), QString("/")); |
|
int pos = normalizedDestination.lastIndexOf("/"); |
|
if (pos != -1) { |
|
QString newpath = normalizedDestination.left(pos); |
|
if (!QDir().mkpath(newpath)) { |
|
qDebug() << "can't create a new path at " << newpath; |
|
} |
|
} |
|
} |
|
return QFile::copy(source, normalizedDestination); |
|
} |
|
|
|
bool UBFileSystemUtils::copy(const QString &source, const QString &destination, bool overwrite) |
|
{ |
|
if (QFileInfo(source).isDir()) { |
|
return copyDir(source, destination); |
|
} else { |
|
return copyFile(source, destination, overwrite); |
|
} |
|
} |
|
|
|
bool UBFileSystemUtils::deleteFile(const QString &path) |
|
{ |
|
QFile f(path); |
|
f.setPermissions(path, QFile::ReadOwner | QFile::WriteOwner); |
|
return f.remove(); |
|
} |
|
|
|
QString UBFileSystemUtils::defaultTempDirPath() |
|
{ |
|
return QStandardPaths::writableLocation(QStandardPaths::TempLocation) + "/" + defaultTempDirName(); |
|
} |
|
|
|
QString UBFileSystemUtils::createTempDir(const QString& templateString, bool autoDeleteOnExit) |
|
{ |
|
QString appTempDir = QStandardPaths::writableLocation(QStandardPaths::TempLocation) |
|
+ "/" + templateString; |
|
|
|
int index = 0; |
|
QDir dir; |
|
|
|
do |
|
{ |
|
index++; |
|
QString dirName = appTempDir + QString("%1").arg(index); |
|
dir = QDir(dirName); |
|
} |
|
while(dir.exists() && index < 10000); |
|
|
|
dir.mkpath(dir.path()); |
|
|
|
if (autoDeleteOnExit) |
|
UBFileSystemUtils::sTempDirToCleanUp << dir.path(); |
|
|
|
return dir.path(); |
|
} |
|
|
|
|
|
QString UBFileSystemUtils::nextAvailableFileName(const QString& filename, const QString& inter) |
|
{ |
|
QFile f(filename); |
|
|
|
if (!f.exists()) |
|
return filename; |
|
|
|
int index = 0; |
|
|
|
QString uniqueFilename; |
|
QFileInfo fi(filename); |
|
|
|
QString base = fi.dir().path() + "/" + fi.baseName(); |
|
QString suffix = fi.suffix(); |
|
|
|
do |
|
{ |
|
index++; |
|
uniqueFilename = base + QString("%1%2").arg(inter).arg(index) + "." + suffix; |
|
f.setFileName(uniqueFilename); |
|
} |
|
while(f.exists() && index < 10000); |
|
|
|
return uniqueFilename; |
|
|
|
} |
|
|
|
|
|
void UBFileSystemUtils::deleteAllTempDirCreatedDuringSession() |
|
{ |
|
foreach (QString dirPath, sTempDirToCleanUp) |
|
{ |
|
qWarning() << "will delete" << dirPath; |
|
|
|
deleteDir(dirPath); |
|
} |
|
} |
|
|
|
|
|
|
|
void UBFileSystemUtils::cleanupGhostTempFolders(const QString& templateString) |
|
{ |
|
QDir dir(QStandardPaths::writableLocation(QStandardPaths::TempLocation)); |
|
foreach (QFileInfo dirContent, dir.entryInfoList(QDir::Dirs |
|
| QDir::NoDotAndDotDot | QDir::Hidden , QDir::Name)) |
|
{ |
|
if (dirContent.fileName().startsWith(templateString)) |
|
{ |
|
deleteDir(dirContent.absoluteFilePath()); |
|
} |
|
} |
|
} |
|
|
|
|
|
QStringList UBFileSystemUtils::allFiles(const QString& pDirPath, bool isRecursive) |
|
{ |
|
QStringList result; |
|
if (pDirPath == "" || pDirPath == "." || pDirPath == "..") |
|
return result; |
|
|
|
QDir dir(pDirPath); |
|
|
|
foreach(QFileInfo dirContent, dir.entryInfoList(QDir::Files | QDir::Dirs | QDir::NoDotAndDotDot , QDir::Name)) |
|
{ |
|
if (isRecursive && dirContent.isDir()) |
|
{ |
|
result << allFiles(dirContent.absoluteFilePath()); |
|
} |
|
else |
|
{ |
|
result << dirContent.absoluteFilePath(); |
|
} |
|
} |
|
return result; |
|
} |
|
|
|
QFileInfoList UBFileSystemUtils::allElementsInDirectory(const QString& pDirPath) |
|
{ |
|
QDir dir = QDir(pDirPath); |
|
dir.setFilter(QDir::Files | QDir::Dirs | QDir::NoDotAndDotDot | QDir::NoSymLinks); |
|
dir.setSorting(QDir::DirsFirst); |
|
|
|
return QFileInfoList(dir.entryInfoList()); |
|
} |
|
|
|
|
|
bool UBFileSystemUtils::deleteDir(const QString& pDirPath) |
|
{ |
|
if (pDirPath == "" || pDirPath == "." || pDirPath == "..") |
|
return false; |
|
|
|
QDir dir(pDirPath); |
|
|
|
if (dir.exists()) |
|
{ |
|
foreach(QFileInfo dirContent, dir.entryInfoList(QDir::Files | QDir::Dirs |
|
| QDir::NoDotAndDotDot | QDir::Hidden | QDir::System , QDir::Name)) |
|
{ |
|
if (dirContent.isDir()) |
|
{ |
|
deleteDir(dirContent.absoluteFilePath()); |
|
} |
|
else |
|
{ |
|
if (!dirContent.dir().remove(dirContent.fileName())) |
|
{ |
|
return false; |
|
} |
|
} |
|
} |
|
} |
|
|
|
return dir.rmdir(pDirPath); |
|
} |
|
|
|
|
|
bool UBFileSystemUtils::copyDir(const QString& pSourceDirPath, const QString& pTargetDirPath) |
|
{ |
|
if (pSourceDirPath == "" || pSourceDirPath == "." || pSourceDirPath == "..") |
|
return false; |
|
|
|
QDir dirSource(pSourceDirPath); |
|
QDir dirTarget(pTargetDirPath); |
|
|
|
if (!dirTarget.mkpath(pTargetDirPath)) |
|
return false; |
|
|
|
bool successSoFar = true; |
|
|
|
foreach(QFileInfo dirContent, dirSource.entryInfoList(QDir::Files | QDir::Dirs |
|
| QDir::NoDotAndDotDot | QDir::Hidden , QDir::Name)) |
|
{ |
|
if (successSoFar) |
|
{ |
|
if (dirContent.isDir()) |
|
{ |
|
successSoFar = copyDir(pSourceDirPath + "/" + dirContent.fileName(), pTargetDirPath + "/" + dirContent.fileName()); |
|
} |
|
else |
|
{ |
|
QFile f(pSourceDirPath + "/" + dirContent.fileName()); |
|
successSoFar = f.copy(pTargetDirPath + "/" + dirContent.fileName()); |
|
} |
|
} |
|
else |
|
{ |
|
break; |
|
} |
|
} |
|
|
|
return successSoFar; |
|
} |
|
|
|
|
|
bool UBFileSystemUtils::moveDir(const QString& pSourceDirPath, const QString& pTargetDirPath) |
|
{ |
|
bool copySuccess = copyDir(pSourceDirPath, pTargetDirPath); |
|
|
|
if (copySuccess) |
|
{ |
|
return deleteDir(pSourceDirPath); |
|
} |
|
else |
|
{ |
|
return false; |
|
} |
|
} |
|
|
|
|
|
|
|
QString UBFileSystemUtils::cleanName(const QString& name) |
|
{ |
|
QString result = name; |
|
result = result.remove("/"); |
|
result = result.remove(":"); |
|
result = result.remove("?"); |
|
result = result.remove("*"); |
|
result = result.remove("\\"); |
|
|
|
//http://support.microsoft.com/kb/177506 |
|
|
|
result = result.remove("<"); |
|
result = result.remove(">"); |
|
result = result.remove("|"); |
|
|
|
return result; |
|
} |
|
|
|
QString UBFileSystemUtils::normalizeFilePath(const QString& pFilePath) |
|
{ |
|
QString result = pFilePath; |
|
return result.replace("\\", "/"); |
|
} |
|
|
|
QString UBFileSystemUtils::digitFileFormat(const QString& s, int digit) |
|
{ |
|
return s.arg(digit, 3, 10, QLatin1Char('0')); |
|
} |
|
|
|
|
|
QString UBFileSystemUtils::thumbnailPath(const QString& path) |
|
{ |
|
QFileInfo pathInfo(path); |
|
|
|
return pathInfo.dir().absolutePath() + "/" + pathInfo.completeBaseName() + ".thumbnail.png"; |
|
} |
|
|
|
QString UBFileSystemUtils::extension(const QString& fileName) |
|
{ |
|
QString extension(""); |
|
|
|
int lastDotIndex = fileName.lastIndexOf("."); |
|
|
|
if (lastDotIndex > 0) |
|
{ |
|
extension = fileName.right(fileName.length() - lastDotIndex - 1).toLower(); |
|
|
|
if (extension.endsWith("/") || extension.endsWith("\\")) |
|
extension = extension.left(extension.length() - 1); |
|
} |
|
|
|
return extension; |
|
} |
|
|
|
QString UBFileSystemUtils::lastPathComponent(const QString& path) |
|
{ |
|
QString lastPathComponent = normalizeFilePath(path); |
|
|
|
int lastSeparatorIndex = lastPathComponent.lastIndexOf("/"); |
|
|
|
if (lastSeparatorIndex + 1 == path.length()) { |
|
lastPathComponent = lastPathComponent.left(lastPathComponent.length() - 1); |
|
lastSeparatorIndex = lastPathComponent.lastIndexOf("/"); |
|
} |
|
|
|
if (lastSeparatorIndex > 0){ |
|
lastPathComponent = lastPathComponent.right(lastPathComponent.length() - lastSeparatorIndex - 1); |
|
} |
|
else { |
|
return 0; |
|
} |
|
|
|
return lastPathComponent; |
|
} |
|
|
|
QString UBFileSystemUtils::mimeTypeFromFileName(const QString& fileName) |
|
{ |
|
QString ext = extension(fileName); |
|
|
|
if (ext == "xls" || ext == "xlsx") return "application/msexcel"; |
|
if (ext == "ppt" || ext == "pptx") return "application/mspowerpoint"; |
|
if (ext == "ief") return "image/ief"; |
|
if (ext == "m3u") return "audio/x-mpegurl"; |
|
if (ext == "key") return "application/x-iwork-keynote-sffkeynote"; |
|
if (ext == "odf") return "application/vnd.oasis.opendocument.formula"; |
|
if (ext == "aif" || ext == "aiff" || ext == "aifc") return "audio/x-aiff"; |
|
if (ext == "odp") return "application/vnd.oasis.opendocument.presentation"; |
|
if (ext == "xml") return "application/xml"; |
|
if (ext == "rgb") return "image/x-rgb"; |
|
if (ext == "ods") return "application/vnd.oasis.opendocument.spreadsheet"; |
|
if (ext == "rtf") return "text/rtf"; |
|
if (ext == "odt") return "application/vnd.oasis.opendocument.text"; |
|
if (ext == "xbm") return "image/x-xbitmap"; |
|
if (ext == "lsx" || ext == "lsf") return "video/x-la-asf"; |
|
if (ext == "jfif") return "image/pipeg"; |
|
if (ext == "ppm") return "image/x-portable-pixmap"; |
|
if (ext == "csv") return "text/csv"; |
|
if (ext == "pgm") return "image/x-portable-graymap"; |
|
if (ext == "odc") return "application/vnd.oasis.opendocument.chart"; |
|
if (ext == "odb") return "application/vnd.oasis.opendocument.database"; |
|
if (ext == "cmx") return "image/x-cmx"; |
|
if (ext == "ico") return "image/x-icon"; |
|
if (ext == "mp3") return "audio/mpeg"; |
|
if (ext == "wav") return "audio/x-wav"; |
|
if (ext == "pbm") return "image/x-portable-bitmap"; |
|
if (ext == "ras") return "image/x-cmu-raster"; |
|
if (ext == "txt") return "text/plain"; |
|
if (ext == "xpm") return "image/x-xpixmap"; |
|
if (ext == "ra" || ext == "ram") return "audio/x-pn-realaudio"; |
|
if (ext == "numbers") return "application/x-iwork-numbers-sffnumbers"; |
|
if (ext == "snd" || ext == "au") return "audio/basic"; |
|
if (ext == "zip") return "application/zip"; |
|
if (ext == "pages") return "application/x-iwork-pages-sffpages"; |
|
if (ext == "movie") return "video/x-sgi-movie"; |
|
if (ext == "xwd") return "image/x-xwindowdump"; |
|
if (ext == "pnm") return "image/x-portable-anymap"; |
|
if (ext == "cod") return "image/cis-cod"; |
|
if (ext == "doc" || ext == "docx") return "application/msword"; |
|
if (ext == "html") return "text/html"; |
|
if (ext == "mid" || ext == "rmi") return "audio/mid"; |
|
if (ext == "jpeg" || ext == "jpg" || ext == "jpe") return "image/jpeg"; |
|
if (ext == "png") return "image/png"; |
|
if (ext == "bmp") return "image/bmp"; |
|
if (ext == "tiff" || ext == "tif") return "image/tiff"; |
|
if (ext == "gif") return "image/gif"; |
|
if (ext == "svg" || ext == "svgz") return "image/svg+xml"; |
|
if (ext == "pdf") return "application/pdf"; |
|
if (ext == "mov" || ext == "qt") return "video/quicktime"; |
|
if (ext == "mpg" || ext == "mpeg" || ext == "mp2" || ext == "mpe" || ext == "mpa" || ext == "mpv2") return "video/mpeg"; |
|
if (ext == "mp4") return "video/mp4"; |
|
if (ext == "asf" || ext == "asx" || ext == "asr") return "video/x-ms-asf"; |
|
if (ext == "wmv") return "video/x-ms-wmv"; |
|
if (ext == "wvx") return "video/x-ms-wvx"; |
|
if (ext == "wm") return "video/x-ms-wm"; |
|
if (ext == "wmx") return "video/x-ms-wmx"; |
|
if (ext == "avi") return "video/x-msvideo"; |
|
if (ext == "ogv") return "video/ogg"; |
|
if (ext == "flv") return "video/x-flv"; // TODO UB 4.x ... we need to be smarter ... flash may need an external plugin :-( |
|
if (ext == "m4v") return "video/x-m4v"; |
|
// W3C widget |
|
if (ext == "wgt") return "application/widget"; |
|
if (ext == "wgs") return "application/search"; |
|
// Apple widget |
|
if (ext == "wdgt") return "application/vnd.apple-widget"; //mime type invented by us :-( |
|
if (ext == "swf") return "application/x-shockwave-flash"; |
|
|
|
return ""; |
|
|
|
} |
|
|
|
|
|
QString UBFileSystemUtils::fileExtensionFromMimeType(const QString& pMimeType) |
|
{ |
|
// TODO UB 4.x map from config file, based on a "good" source |
|
|
|
if (pMimeType == "application/msexcel") return "xls"; |
|
if (pMimeType == "application/mspowerpoint") return "ppt"; |
|
if (pMimeType == "image/ief") return "ief"; |
|
if (pMimeType == "audio/x-mpegurl") return "m3u"; |
|
if (pMimeType == "application/x-iwork-keynote-sffkeynote") return "key"; |
|
if (pMimeType == "application/vnd.oasis.opendocument.formula") return "odf"; |
|
if (pMimeType == "audio/x-aiff") return "aif"; |
|
if (pMimeType == "application/vnd.oasis.opendocument.presentation") return "odp"; |
|
if (pMimeType == "application/xml") return "xml"; |
|
if (pMimeType == "image/x-rgb") return "rgb"; |
|
if (pMimeType == "application/vnd.oasis.opendocument.spreadsheet") return "ods"; |
|
if (pMimeType == "text/rtf") return "rtf"; |
|
if (pMimeType == "application/vnd.oasis.opendocument.text") return "odt"; |
|
if (pMimeType == "image/x-xbitmap") return "xbm"; |
|
if (pMimeType == "video/x-la-asf") return "lsx"; |
|
if (pMimeType == "image/pipeg") return "jfif"; |
|
if (pMimeType == "image/x-portable-pixmap") return "ppm"; |
|
if (pMimeType == "text/csv") return "csv"; |
|
if (pMimeType == "image/x-portable-graymap") return "pgm"; |
|
if (pMimeType == "application/vnd.oasis.opendocument.chart") return "odc"; |
|
if (pMimeType == "application/vnd.oasis.opendocument.database") return "odb"; |
|
if (pMimeType == "image/x-cmx") return "cmx"; |
|
if (pMimeType == "image/x-icon") return "ico"; |
|
if (pMimeType == "audio/mpeg") return "mp3"; |
|
if (pMimeType == "audio/x-wav") return "wav"; |
|
if (pMimeType == "image/x-portable-bitmap") return "pbm"; |
|
if (pMimeType == "image/x-cmu-raster") return "ras"; |
|
if (pMimeType == "text/plain") return "txt"; |
|
if (pMimeType == "image/x-xpixmap") return "xpm"; |
|
if (pMimeType == "audio/x-pn-realaudio") return "ram"; |
|
if (pMimeType == "application/x-iwork-numbers-sffnumbers") return "numbers"; |
|
if (pMimeType == "audio/basic") return "snd"; |
|
if (pMimeType == "application/zip") return "zip"; |
|
if (pMimeType == "application/x-iwork-pages-sffpages") return "pages"; |
|
if (pMimeType == "video/x-sgi-movie") return "movie"; |
|
if (pMimeType == "image/x-xwindowdump") return "xwd"; |
|
if (pMimeType == "image/x-portable-anymap") return "pnm"; |
|
if (pMimeType == "image/cis-cod") return "cod"; |
|
if (pMimeType == "application/msword") return "doc"; |
|
if (pMimeType == "text/html") return "html"; |
|
if (pMimeType == "audio/mid") return "mid"; |
|
if (pMimeType == "image/jpeg") return "jpeg"; |
|
if (pMimeType == "image/png") return "png"; |
|
if (pMimeType == "image/bmp") return "bmp"; |
|
if (pMimeType == "image/tiff") return "tiff"; |
|
if (pMimeType == "image/gif") return "gif"; |
|
if (pMimeType == "image/svg+xml") return "svg"; |
|
if (pMimeType == "application/pdf") return "pdf"; |
|
if (pMimeType == "video/quicktime") return "mov"; |
|
if (pMimeType == "video/mpeg") return "mpg"; |
|
if (pMimeType == "video/mp4") return "mp4"; |
|
if (pMimeType == "video/x-ms-asf") return "asf"; |
|
if (pMimeType == "video/x-ms-wmv") return "wmv"; |
|
if (pMimeType == "video/x-ms-wvx") return "wvx"; |
|
if (pMimeType == "video/x-ms-wm") return "wm"; |
|
if (pMimeType == "video/x-ms-wmx") return "wmx"; |
|
if (pMimeType == "video/x-msvideo") return "avi"; |
|
if (pMimeType == "video/ogg") return "ogv"; |
|
if (pMimeType == "video/x-flv") return "flv"; |
|
if (pMimeType == "video/x-m4v") return "m4v"; |
|
if (pMimeType == "application/widget") return "wgt"; |
|
if (pMimeType == "application/vnd.apple-widget") return "wdgt"; //mime type invented by us :-( |
|
if (pMimeType == "application/x-shockwave-flash") return "swf"; |
|
|
|
return ""; |
|
|
|
} |
|
|
|
|
|
UBMimeType::Enum UBFileSystemUtils::mimeTypeFromString(const QString& typeString) |
|
{ |
|
UBMimeType::Enum type = UBMimeType::UNKNOWN; |
|
|
|
if (typeString == "image/jpeg" |
|
|| typeString == "image/png" |
|
|| typeString == "image/gif" |
|
|| typeString == "image/tiff" |
|
|| typeString == "image/bmp") |
|
{ |
|
type = UBMimeType::RasterImage; |
|
} |
|
else if (typeString == "image/svg+xml") |
|
{ |
|
type = UBMimeType::VectorImage; |
|
} |
|
else if (typeString == "application/vnd.apple-widget") |
|
{ |
|
type = UBMimeType::AppleWidget; |
|
} |
|
else if (typeString == "application/widget") |
|
{ |
|
type = UBMimeType::W3CWidget; |
|
} |
|
else if (typeString.startsWith("video/")) |
|
{ |
|
type = UBMimeType::Video; |
|
} |
|
else if (typeString.startsWith("audio/")) |
|
{ |
|
type = UBMimeType::Audio; |
|
} |
|
else if (typeString.startsWith("application/x-shockwave-flash")) |
|
{ |
|
type = UBMimeType::Flash; |
|
} |
|
else if (typeString.startsWith("application/pdf")) |
|
{ |
|
type = UBMimeType::PDF; |
|
} |
|
/* else if (typeString.startsWith("application/vnd.mnemis-uniboard-tool")) |
|
{ |
|
type = UBMimeType::UniboardTool; |
|
} */ |
|
|
|
else if (typeString.startsWith("application/openboard-tool")) |
|
{ |
|
type = UBMimeType::OpenboardTool; |
|
} |
|
return type; |
|
|
|
} |
|
|
|
UBMimeType::Enum UBFileSystemUtils::mimeTypeFromUrl(const QUrl& url) |
|
{ |
|
return mimeTypeFromString(mimeTypeFromFileName(url.toString())); |
|
} |
|
|
|
QString UBFileSystemUtils::getFirstExistingFileFromList(const QString& path, const QStringList& files) |
|
{ |
|
|
|
QString fullpath = path; |
|
|
|
if (!path.endsWith("/")) |
|
{ |
|
fullpath += "/"; |
|
} |
|
|
|
foreach(QString filename, files) |
|
{ |
|
QFile file; |
|
|
|
file.setFileName(fullpath + filename); |
|
|
|
if (file.exists()) |
|
{ |
|
return fullpath + filename; |
|
} |
|
} |
|
|
|
return ""; |
|
|
|
} |
|
|
|
|
|
bool UBFileSystemUtils::compressDirInZip(const QDir& pDir, const QString& pDestPath, QuaZipFile *pOutZipFile, bool pRootDocumentFolder, UBProcessingProgressListener* progressListener) |
|
{ |
|
QFileInfoList files = pDir.entryInfoList(QDir::AllDirs | QDir::Files | QDir::NoDotAndDotDot); |
|
|
|
QStringList filters; |
|
filters << "*.svg"; |
|
QFileInfoList pageFiles = pDir.entryInfoList(filters); |
|
|
|
foreach (QFileInfo file, files) |
|
{ |
|
if (file.isDir()) |
|
{ |
|
QDir dir(file.absoluteFilePath()); |
|
if (!compressDirInZip(dir, pDestPath + dir.dirName() + "/" , pOutZipFile, false)) |
|
{ |
|
return false; |
|
} |
|
} |
|
|
|
if (file.isFile()) |
|
{ |
|
QString objectType; |
|
if (pRootDocumentFolder) |
|
{ |
|
objectType = "Page"; |
|
} |
|
else |
|
{ |
|
objectType = pDir.dirName(); |
|
} |
|
|
|
if (!pRootDocumentFolder) |
|
{ |
|
if (progressListener) |
|
progressListener->processing(objectType, files.indexOf(file), files.size()); |
|
} |
|
// we ignore thumbnails message because it is very fast. |
|
else if (progressListener && file.suffix() == "svg") |
|
{ |
|
progressListener->processing(objectType, pageFiles.indexOf(file), pageFiles.size()); |
|
} |
|
|
|
QFile inFile(file.absoluteFilePath()); |
|
if(!inFile.open(QIODevice::ReadOnly)) |
|
{ |
|
qWarning() << "Compression of file" << inFile.fileName() << " failed. Cause: inFile.open(): " << inFile.errorString(); |
|
return false; |
|
} |
|
|
|
qDebug() << "will open" << pDestPath << file.fileName() << inFile.fileName(); |
|
|
|
if(!pOutZipFile->open(QIODevice::WriteOnly, QuaZipNewInfo(pDestPath + file.fileName(), inFile.fileName()))) |
|
{ |
|
qWarning() << "Compression of file" << inFile.fileName() << " failed. Cause: outFile.open(): " << pOutZipFile->getZipError(); |
|
inFile.close(); |
|
return false; |
|
} |
|
|
|
pOutZipFile->write(inFile.readAll()); |
|
if(pOutZipFile->getZipError() != UNZ_OK) |
|
{ |
|
qWarning() << "Compression of file" << inFile.fileName() << " failed. Cause: outFile.write(): " << pOutZipFile->getZipError(); |
|
|
|
inFile.close(); |
|
pOutZipFile->close(); |
|
return false; |
|
} |
|
|
|
pOutZipFile->close(); |
|
if(pOutZipFile->getZipError() != UNZ_OK) |
|
{ |
|
qWarning() << "Compression of file" << inFile.fileName() << " failed. Cause: outFile.close(): " << pOutZipFile->getZipError(); |
|
|
|
inFile.close(); |
|
return false; |
|
} |
|
|
|
inFile.close(); |
|
} |
|
} |
|
|
|
return true; |
|
} |
|
|
|
|
|
|
|
bool UBFileSystemUtils::expandZipToDir(const QFile& pZipFile, const QDir& pTargetDir) |
|
{ |
|
QuaZip zip(pZipFile.fileName()); |
|
|
|
if(!zip.open(QuaZip::mdUnzip)) |
|
{ |
|
qWarning() << "ZIP expand failed. Cause zip.open(): " << zip.getZipError(); |
|
return false; |
|
} |
|
|
|
zip.setFileNameCodec("UTF-8"); |
|
QuaZipFileInfo info; |
|
QuaZipFile file(&zip); |
|
|
|
QString documentRootFolder = pTargetDir.absolutePath(); |
|
|
|
if(!pTargetDir.exists()) |
|
pTargetDir.mkpath(documentRootFolder); |
|
|
|
QFile out; |
|
char c; |
|
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() << "ZIP expand failed. Cause: getCurrentFileInfo(): " << zip.getZipError(); |
|
return false; |
|
} |
|
|
|
if(!file.open(QIODevice::ReadOnly)) |
|
{ |
|
qWarning() << "ZIP expand failed. Cause: file.open(): " << zip.getZipError(); |
|
return false; |
|
} |
|
|
|
if(file.getZipError()!= UNZ_OK) |
|
{ |
|
qWarning() << "ZIP expand failed. Cause: file.getFileName(): " << zip.getZipError(); |
|
return false; |
|
} |
|
|
|
QString newFileName = documentRootFolder + "/" + file.getActualFileName(); |
|
QFileInfo newFileInfo(newFileName); |
|
QDir root(documentRootFolder); |
|
root.mkpath(newFileInfo.absolutePath()); |
|
|
|
out.setFileName(newFileName); |
|
out.open(QIODevice::WriteOnly); |
|
|
|
// 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() << "ZIP expand failed. Cause: Unable to write file"; |
|
// this may happen if we are decompressing a directory |
|
} |
|
|
|
while(file.getChar(&c)) |
|
out.putChar(c); |
|
|
|
out.close(); |
|
|
|
if(file.getZipError()!= UNZ_OK) |
|
{ |
|
qWarning() << "ZIP expand failed. Cause: " << zip.getZipError(); |
|
return false; |
|
} |
|
|
|
if(!file.atEnd()) |
|
{ |
|
qWarning() << "ZIP expand failed. Cause: read all but not EOF"; |
|
return false; |
|
} |
|
|
|
file.close(); |
|
|
|
if(file.getZipError()!= UNZ_OK) |
|
{ |
|
qWarning() << "ZIP expand failed. Cause: file.close(): " << file.getZipError(); |
|
return false; |
|
} |
|
|
|
} |
|
|
|
zip.close(); |
|
|
|
if(zip.getZipError()!= UNZ_OK) |
|
{ |
|
qWarning() << "ZIP expand failed. Cause: zip.close(): " << zip.getZipError(); |
|
return false; |
|
} |
|
|
|
return true; |
|
} |
|
|
|
|
|
QString UBFileSystemUtils::md5InHex(const QByteArray &pByteArray) |
|
{ |
|
MD5_CTX ctx; |
|
MD5_Init(&ctx); |
|
MD5_Update(&ctx, pByteArray.data(), pByteArray.size()); |
|
|
|
unsigned char result[16]; |
|
MD5_Final(result, &ctx); |
|
|
|
return QString(QByteArray((char *)result, 16).toHex()); |
|
} |
|
|
|
QString UBFileSystemUtils::md5(const QByteArray &pByteArray) |
|
{ |
|
MD5_CTX ctx; |
|
MD5_Init(&ctx); |
|
MD5_Update(&ctx, pByteArray.data(), pByteArray.size()); |
|
|
|
unsigned char result[16]; |
|
MD5_Final(result, &ctx); |
|
QString s; |
|
|
|
for(int i = 0; i < 16; i++) |
|
{ |
|
s += QChar(result[i]); |
|
} |
|
|
|
return s; |
|
} |
|
|
|
QString UBFileSystemUtils::readTextFile(QString path) |
|
{ |
|
QFile file(path); |
|
|
|
if (file.open(QIODevice::ReadOnly | QIODevice::Text)) |
|
{ |
|
QTextStream in(&file); |
|
return in.readAll(); |
|
} |
|
|
|
return ""; |
|
}
|
|
|