File indexing completed on 2024-05-12 04:46:01
0001 #include "compressedfile.h" 0002 0003 #include <KArchive/KTar> 0004 #include <KArchive/KZip> 0005 #include <KArchive/kcompressiondevice.h> 0006 #include <KArchive/kfilterdev.h> 0007 0008 #if (defined Q_OS_LINUX || defined Q_OS_FREEBSD) && !defined Q_OS_ANDROID 0009 #include <KArchive/k7zip.h> 0010 #endif 0011 0012 #include <KArchive/kar.h> 0013 0014 #include <QDirIterator> 0015 #include <QDebug> 0016 0017 #include <MauiKit3/FileBrowsing/fmstatic.h> 0018 0019 0020 CompressedFile::CompressedFile(QObject *parent) 0021 : QObject(parent) 0022 , m_model(new CompressedFileModel(this)) 0023 { 0024 } 0025 0026 CompressedFileModel::CompressedFileModel(QObject *parent) 0027 : MauiList(parent) 0028 { 0029 } 0030 0031 const FMH::MODEL_LIST &CompressedFileModel::items() const 0032 { 0033 return m_list; 0034 } 0035 0036 void CompressedFileModel::setUrl(const QUrl &url) 0037 { 0038 if(m_url == url) 0039 { 0040 return; 0041 } 0042 0043 qDebug() << "@gadominguez File:fm.cpp Funcion: getEntries Url:" << url.toString(); 0044 0045 KArchive *kArch = CompressedFile::getKArchiveObject(url); 0046 kArch->open(QIODevice::ReadOnly); 0047 assert(kArch->isOpen() == true); 0048 if (kArch->isOpen()) 0049 { 0050 Q_EMIT this->preListChanged(); 0051 m_list.clear(); 0052 0053 qDebug() << "@gadominguez File:fm.cpp Funcion: getEntries Entries:" << kArch->directory()->entries(); 0054 0055 const auto entries = kArch->directory()->entries(); 0056 for (const auto &entry : entries) 0057 { 0058 const auto e = kArch->directory()->entry(entry); 0059 this->m_list << FMH::MODEL{{FMH::MODEL_KEY::LABEL, e->name()}, {FMH::MODEL_KEY::ICON, e->isDirectory() ? "folder" : FMStatic::getIconName(e->name())}, {FMH::MODEL_KEY::DATE, e->date().toString()}}; 0060 0061 } 0062 0063 Q_EMIT this->postListChanged(); 0064 Q_EMIT this->countChanged (); 0065 } 0066 } 0067 0068 void CompressedFile::extract(const QUrl &where, const QString &directory) 0069 { 0070 if (!m_url.isLocalFile()) 0071 return; 0072 0073 qDebug() << "@gadominguez File:fm.cpp Funcion: extractFile " 0074 << "URL: " << m_url << "WHERE: " << where.toString() << " DIR: " << directory; 0075 0076 QString where_ = where.toLocalFile() + "/" + directory; 0077 0078 auto kArch = CompressedFile::getKArchiveObject(m_url); 0079 kArch->open(QIODevice::ReadOnly); 0080 qDebug() << "@gadominguez File:fm.cpp Funcion: extractFile " << kArch->directory()->entries(); 0081 assert(kArch->isOpen() == true); 0082 0083 if (kArch->isOpen()) 0084 { 0085 if(kArch->directory()->copyTo(where_, true)) 0086 { 0087 Q_EMIT this->extractionFinished (where); 0088 } 0089 0090 kArch->close (); 0091 0092 } 0093 delete kArch; 0094 } 0095 0096 /* 0097 * 0098 * CompressTypeSelected is an integer and has to be acorrding with order in Dialog.qml 0099 * 0100 */ 0101 bool CompressedFile::compress(const QVariantList &files, const QUrl &where, const QString &fileName, const int &compressTypeSelected) 0102 { 0103 bool error = true; 0104 assert(compressTypeSelected >= 0 && compressTypeSelected <= 8); 0105 for (const auto &uri : files) { 0106 qDebug() << "@gadominguez File:fm.cpp Funcion: compress " << QUrl(uri.toString()).toLocalFile() << " " << fileName; 0107 0108 if (!QFileInfo(QUrl(uri.toString()).toLocalFile()).isDir()) { 0109 auto file = QFile(QUrl(uri.toString()).toLocalFile()); 0110 file.open(QIODevice::ReadWrite); 0111 if (file.isOpen() == true) { 0112 switch (compressTypeSelected) { 0113 case 0: //.ZIP 0114 { 0115 auto kzip = new KZip(QUrl(where.toString() + "/" + fileName + ".zip").toLocalFile()); 0116 kzip->open(QIODevice::ReadWrite); 0117 assert(kzip->isOpen() == true); 0118 0119 error = kzip->writeFile(uri.toString().remove(where.toString(), Qt::CaseSensitivity::CaseSensitive), // Mirror file path in compressed file from current directory 0120 file.readAll(), 0121 0100775, 0122 QFileInfo(file).owner(), 0123 QFileInfo(file).group(), 0124 QDateTime(), 0125 QDateTime(), 0126 QDateTime()); 0127 (void)kzip->close(); 0128 // WriteFile returns if the file was written or not, 0129 // but this function returns if some error occurs so for this reason it is needed to toggle the value 0130 error = !error; 0131 break; 0132 } 0133 case 1: // .TAR 0134 { 0135 auto ktar = new KTar(QUrl(where.toString() + "/" + fileName + ".tar").toLocalFile()); 0136 ktar->open(QIODevice::ReadWrite); 0137 assert(ktar->isOpen() == true); 0138 error = ktar->writeFile(uri.toString().remove(where.toString(), Qt::CaseSensitivity::CaseSensitive), // Mirror file path in compressed file from current directory 0139 file.readAll(), 0140 0100775, 0141 QFileInfo(file).owner(), 0142 QFileInfo(file).group(), 0143 QDateTime(), 0144 QDateTime(), 0145 QDateTime()); 0146 (void)ktar->close(); 0147 break; 0148 } 0149 case 2: //.7ZIP 0150 { 0151 #ifdef K7ZIP_H 0152 0153 // TODO: KArchive no permite comprimir ficheros del mismo modo que con TAR o ZIP. Hay que hacerlo de otra forma y requiere disponer de una libreria actualizada de KArchive. 0154 auto k7zip = new K7Zip(QUrl(where.toString() + "/" + fileName + ".7z").toLocalFile()); 0155 k7zip->open(QIODevice::ReadWrite); 0156 assert(k7zip->isOpen() == true); 0157 error = k7zip->writeFile(uri.toString().remove(where.toString(), Qt::CaseSensitivity::CaseSensitive), // Mirror file path in compressed file from current directory 0158 file.readAll(), 0159 0100775, 0160 QFileInfo(file).owner(), 0161 QFileInfo(file).group(), 0162 QDateTime(), 0163 QDateTime(), 0164 QDateTime()); 0165 k7zip->close(); 0166 // WriteFile returns if the file was written or not, 0167 // but this function returns if some error occurs so for this reason it is needed to toggle the value 0168 error = !error; 0169 #endif 0170 break; 0171 } 0172 case 3: //.AR 0173 { 0174 // TODO: KArchive no permite comprimir ficheros del mismo modo que con TAR o ZIP. Hay que hacerlo de otra forma y requiere disponer de una libreria actualizada de KArchive. 0175 auto kar = new KAr(QUrl(where.toString() + "/" + fileName + ".ar").toLocalFile()); 0176 kar->open(QIODevice::ReadWrite); 0177 assert(kar->isOpen() == true); 0178 error = kar->writeFile(uri.toString().remove(where.toString(), Qt::CaseSensitivity::CaseSensitive), // Mirror file path in compressed file from current directory 0179 file.readAll(), 0180 0100775, 0181 QFileInfo(file).owner(), 0182 QFileInfo(file).group(), 0183 QDateTime(), 0184 QDateTime(), 0185 QDateTime()); 0186 (void)kar->close(); 0187 // WriteFile returns if the file was written or not, 0188 // but this function returns if some error occurs so for this reason it is needed to toggle the value 0189 error = !error; 0190 break; 0191 } 0192 default: 0193 qDebug() << "ERROR. COMPRESSED TYPE SELECTED NOT COMPATIBLE"; 0194 break; 0195 } 0196 } else { 0197 qDebug() << "ERROR. CURRENT USER DOES NOT HAVE PEMRISSION FOR WRITE IN THE CURRENT DIRECTORY."; 0198 error = true; 0199 } 0200 } else { 0201 qDebug() << "Dir: " << QUrl(uri.toString()).toLocalFile(); 0202 auto dir = QDirIterator(QUrl(uri.toString()).toLocalFile(), QDirIterator::Subdirectories); 0203 switch (compressTypeSelected) { 0204 case 0: //.ZIP 0205 { 0206 auto kzip = new KZip(QUrl(where.toString() + "/" + fileName + ".zip").toLocalFile()); 0207 kzip->open(QIODevice::ReadWrite); 0208 assert(kzip->isOpen() == true); 0209 while (dir.hasNext()) { 0210 auto entrie = dir.next(); 0211 0212 qDebug() << entrie << " " << where.toString() << QFileInfo(entrie).isFile(); 0213 if (QFileInfo(entrie).isFile() == true) { 0214 auto file = QFile(entrie); 0215 file.open(QIODevice::ReadOnly); 0216 qDebug() << entrie << entrie.remove(QUrl(where).toLocalFile(), Qt::CaseSensitivity::CaseSensitive); 0217 error = kzip->writeFile(entrie.remove(QUrl(where).toLocalFile(), Qt::CaseSensitivity::CaseSensitive), // Mirror file path in compressed file from current directory 0218 file.readAll(), 0219 0100775, 0220 QFileInfo(file).owner(), 0221 QFileInfo(file).group(), 0222 QDateTime(), 0223 QDateTime(), 0224 QDateTime()); 0225 // WriteFile returns if the file was written or not, 0226 // but this function returns if some error occurs so for this reason it is needed to toggle the value 0227 error = !error; 0228 } 0229 } 0230 (void)kzip->close(); 0231 break; 0232 } 0233 case 1: // .TAR 0234 { 0235 auto ktar = new KTar(QUrl(where.toString() + "/" + fileName + ".tar").toLocalFile()); 0236 ktar->open(QIODevice::ReadWrite); 0237 assert(ktar->isOpen() == true); 0238 while (dir.hasNext()) { 0239 auto entrie = dir.next(); 0240 0241 qDebug() << entrie << " " << where.toString() << QFileInfo(entrie).isFile(); 0242 if (QFileInfo(entrie).isFile() == true) { 0243 auto file = QFile(entrie); 0244 file.open(QIODevice::ReadOnly); 0245 qDebug() << entrie << entrie.remove(QUrl(where).toLocalFile(), Qt::CaseSensitivity::CaseSensitive); 0246 error = ktar->writeFile(entrie.remove(QUrl(where).toLocalFile(), Qt::CaseSensitivity::CaseSensitive), // Mirror file path in compressed file from current directory 0247 file.readAll(), 0248 0100775, 0249 QFileInfo(file).owner(), 0250 QFileInfo(file).group(), 0251 QDateTime(), 0252 QDateTime(), 0253 QDateTime()); 0254 // WriteFile returns if the file was written or not, 0255 // but this function returns if some error occurs so for this reason it is needed to toggle the value 0256 error = !error; 0257 } 0258 } 0259 (void)ktar->close(); 0260 break; 0261 } 0262 case 2: //.7ZIP 0263 { 0264 #ifdef K7ZIP_H 0265 0266 auto k7zip = new K7Zip(QUrl(where.toString() + "/" + fileName + ".7z").toLocalFile()); 0267 k7zip->open(QIODevice::ReadWrite); 0268 assert(k7zip->isOpen() == true); 0269 while (dir.hasNext()) { 0270 auto entrie = dir.next(); 0271 0272 qDebug() << entrie << " " << where.toString() << QFileInfo(entrie).isFile(); 0273 if (QFileInfo(entrie).isFile() == true) { 0274 auto file = QFile(entrie); 0275 file.open(QIODevice::ReadOnly); 0276 qDebug() << entrie << entrie.remove(QUrl(where).toLocalFile(), Qt::CaseSensitivity::CaseSensitive); 0277 error = k7zip->writeFile(entrie.remove(QUrl(where).toLocalFile(), Qt::CaseSensitivity::CaseSensitive), // Mirror file path in compressed file from current directory 0278 file.readAll(), 0279 0100775, 0280 QFileInfo(file).owner(), 0281 QFileInfo(file).group(), 0282 QDateTime(), 0283 QDateTime(), 0284 QDateTime()); 0285 // WriteFile returns if the file was written or not, 0286 // but this function returns if some error occurs so for this reason it is needed to toggle the value 0287 error = !error; 0288 } 0289 } 0290 (void)k7zip->close(); 0291 #endif 0292 break; 0293 } 0294 case 3: //.AR 0295 { 0296 auto kAr = new KAr(QUrl(where.toString() + "/" + fileName + ".ar").toLocalFile()); 0297 kAr->open(QIODevice::ReadWrite); 0298 assert(kAr->isOpen() == true); 0299 while (dir.hasNext()) { 0300 auto entrie = dir.next(); 0301 0302 qDebug() << entrie << " " << where.toString() << QFileInfo(entrie).isFile(); 0303 if (QFileInfo(entrie).isFile() == true) { 0304 auto file = QFile(entrie); 0305 file.open(QIODevice::ReadOnly); 0306 qDebug() << entrie << entrie.remove(QUrl(where).toLocalFile(), Qt::CaseSensitivity::CaseSensitive); 0307 error = kAr->writeFile(entrie.remove(QUrl(where).toLocalFile(), Qt::CaseSensitivity::CaseSensitive), // Mirror file path in compressed file from current directory 0308 file.readAll(), 0309 0100775, 0310 QFileInfo(file).owner(), 0311 QFileInfo(file).group(), 0312 QDateTime(), 0313 QDateTime(), 0314 QDateTime()); 0315 // WriteFile returns if the file was written or not, 0316 // but this function returns if some error occurs so for this reason it is needed to toggle the value 0317 error = !error; 0318 } 0319 } 0320 (void)kAr->close(); 0321 break; 0322 } 0323 default: 0324 qDebug() << "ERROR. COMPRESSED TYPE SELECTED NOT COMPATIBLE"; 0325 break; 0326 } 0327 } 0328 } 0329 0330 // kzip->prepareWriting("Hello00000.txt", "gabridc", "gabridc", 1024, 0100777, QDateTime(), QDateTime(), QDateTime()); 0331 // kzip->writeData("Hello", sizeof("Hello")); 0332 // kzip->finishingWriting(); 0333 0334 return error; 0335 } 0336 0337 KArchive *CompressedFile::getKArchiveObject(const QUrl &url) 0338 { 0339 KArchive *kArch = nullptr; 0340 0341 /* 0342 * This checks depends on type COMPRESSED_MIMETYPES in file fmh.h 0343 */ 0344 qDebug() << "@gadominguez File: fmstatic.cpp Func: getKArchiveObject MimeType: " << FMStatic::getMime(url); 0345 0346 if (FMStatic::getMime(url).contains("application/x-tar") || FMStatic::getMime(url).contains("application/x-compressed-tar")) { 0347 kArch = new KTar(url.toString().split(QString("file://"))[1]); 0348 } else if (FMStatic::getMime(url).contains("application/zip")) { 0349 kArch = new KZip(url.toString().split(QString("file://"))[1]); 0350 } else if (FMStatic::getMime(url).contains("application/x-7z-compressed")) { 0351 #ifdef K7ZIP_H 0352 kArch = new K7Zip(url.toString().split(QString("file://"))[1]); 0353 #endif 0354 } else { 0355 qDebug() << "ERROR. COMPRESSED FILE TYPE UNKOWN " << url.toString(); 0356 } 0357 0358 return kArch; 0359 } 0360 0361 void CompressedFile::setUrl(const QUrl &url) 0362 { 0363 if (m_url == url) 0364 return; 0365 0366 m_url = url; 0367 Q_EMIT this->urlChanged(); 0368 0369 m_model->setUrl(m_url); 0370 } 0371 0372 QUrl CompressedFile::url() const 0373 { 0374 return m_url; 0375 } 0376 0377 CompressedFileModel *CompressedFile::model() const 0378 { 0379 return m_model; 0380 }