|
|
|
/*
|
|
|
|
* 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 3 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, see <http://www.gnu.org/licenses/>.
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include "UBFileSystemUtils.h"
|
|
|
|
|
|
|
|
#include <QtGui>
|
|
|
|
|
|
|
|
#include "quazipfile.h"
|
|
|
|
|
|
|
|
#include <openssl/md5.h>
|
|
|
|
|
|
|
|
#include "core/memcheck.h"
|
|
|
|
|
|
|
|
QStringList UBFileSystemUtils::sTempDirToCleanUp;
|
|
|
|
|
|
|
|
|
|
|
|
UBFileSystemUtils::UBFileSystemUtils()
|
|
|
|
{
|
|
|
|
// NOOP
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
UBFileSystemUtils::~UBFileSystemUtils()
|
|
|
|
{
|
|
|
|
// NOOP
|
|
|
|
}
|
|
|
|
|
|
|
|
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);
|
|
|
|
}
|
|
|
|
|
|
|
|
QString UBFileSystemUtils::defaultTempDirPath()
|
|
|
|
{
|
|
|
|
return QDesktopServices::storageLocation(QDesktopServices::TempLocation) + "/" + defaultTempDirName();
|
|
|
|
}
|
|
|
|
|
|
|
|
QString UBFileSystemUtils::createTempDir(const QString& templateString, bool autoDeleteOnExit)
|
|
|
|
{
|
|
|
|
QString appTempDir = QDesktopServices::storageLocation(QDesktopServices::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(QDesktopServices::storageLocation(QDesktopServices::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)
|
|
|
|
{
|
|
|
|
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 (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);
|
|
|
|
|
|
|
|
dirTarget.mkpath(pTargetDirPath);
|
|
|
|
|
|
|
|
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 "";
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
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();
|
|
|
|
pOutZipFile->close();
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
pOutZipFile->close();
|
|
|
|
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 "";
|
|
|
|
}
|
|
|
|
|