bool MimeTypeChecker::isWantedCollection(const Collection &collection, const QString &wantedMimeType) { if (wantedMimeType.isEmpty() || !collection.isValid()) { return false; } const QStringList contentMimeTypes = collection.contentMimeTypes(); if (contentMimeTypes.isEmpty()) { return false; } foreach (const QString &mimeType, contentMimeTypes) { if (mimeType.isEmpty()) { continue; } if (mimeType == wantedMimeType) { return true; } QMimeDatabase db; const QMimeType mt = db.mimeTypeForName(mimeType); if (!mt.isValid()) { continue; } if (mt.inherits(wantedMimeType)) { return true; } } return false; }
void tst_QMimeDatabase::inheritsPerformance() { // Check performance of inherits(). // This benchmark (which started in 2009 in kmimetypetest.cpp) uses 40 mimetypes. QStringList mimeTypes; mimeTypes << QLatin1String("image/jpeg") << QLatin1String("image/png") << QLatin1String("image/tiff") << QLatin1String("text/plain") << QLatin1String("text/html"); mimeTypes += mimeTypes; mimeTypes += mimeTypes; mimeTypes += mimeTypes; QCOMPARE(mimeTypes.count(), 40); QMimeDatabase db; QMimeType mime = db.mimeTypeForName(QString::fromLatin1("text/x-chdr")); QVERIFY(mime.isValid()); QBENCHMARK { QString match; foreach (const QString &mt, mimeTypes) { if (mime.inherits(mt)) { match = mt; // of course there would normally be a "break" here, but we're testing worse-case // performance here } } QCOMPARE(match, QString::fromLatin1("text/plain")); } // Numbers from 2011, in release mode: // KDE 4.7 numbers: 0.21 msec / 494,000 ticks / 568,345 instr. loads per iteration // QMimeBinaryProvider (with Qt 5): 0.16 msec / NA / 416,049 instr. reads per iteration // QMimeXmlProvider (with Qt 5): 0.062 msec / NA / 172,889 instr. reads per iteration // (but the startup time is way higher) // And memory usage is flat at 200K with QMimeBinaryProvider, while it peaks at 6 MB when // parsing XML, and then keeps being around 4.5 MB for all the in-memory hashes. }
QNetworkReply* Parse::uploadFile(QUrl url, QString name) { QString filePath = url.toLocalFile(); if (!isReady() || !QFile::exists(filePath)) return NULL; if (name.isEmpty()) name = url.fileName(); setEndPoint( "files/"+name); QMimeDatabase db; QMimeType mime = db.mimeTypeForFile(filePath); QFile file(filePath); if (mime.inherits("text/plain")){ if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) return NULL; } else{ if (!file.open(QIODevice::ReadOnly )) return NULL; } initHeaders(); setHeader(QNetworkRequest::ContentTypeHeader, mime.name().toUtf8()); m_conn = connect(this, &BaaS::replyFinished, [=]( QJsonDocument json){ disconnect(m_conn); if ( getHttpCode() == 201 ){ currentObject = json.object(); emit fileUploaded( currentObject); } } ); return request( BaaS::POST, file.readAll() ); }
// create table of file lists qualified for search QHash<SearchWorker::WorkSet, QStringList> SearchWorker::createFileTable(QDir dir, QDir::Filter hidden, QHash<SearchWorker::WorkSet, bool> enabler) { QHash<SearchWorker::WorkSet, QStringList> wtab; QStringList filetypefilters; if (!enabler[SearchWorker::EnableMimeType]) { if (enabler[SearchWorker::EnableTxt]) { filetypefilters.clear(); filetypefilters << "*.txt"; wtab[SearchWorker::EnableTxt] = dir.entryList(filetypefilters, QDir::Files | hidden); } if (enabler[SearchWorker::EnableHtml]) { filetypefilters.clear(); filetypefilters << "*.html" << "*.htm"; wtab[SearchWorker::EnableHtml] = dir.entryList(filetypefilters, QDir::Files | hidden); } if (enabler[SearchWorker::EnableSrc]) { filetypefilters.clear(); filetypefilters << "*.cpp" << "*.c" << "*.h" << "*.py" << "*.sh" << "*.qml" << "*.js"; wtab[SearchWorker::EnableSrc] = dir.entryList(filetypefilters, QDir::Files | hidden); } if (enabler[SearchWorker::EnableApps]) { filetypefilters.clear(); filetypefilters << "*.desktop"; wtab[SearchWorker::EnableApps] = dir.entryList(filetypefilters, QDir::Files | hidden); } if (enabler[SearchWorker::EnableSqlite]) { filetypefilters.clear(); filetypefilters << "*.sqlite" << "*.sqlite3" << "*.db"; wtab[SearchWorker::EnableSqlite] = dir.entryList(filetypefilters, QDir::Files | hidden); } } if (enabler[SearchWorker::EnableMimeType]) { filetypefilters.clear(); QStringList names = dir.entryList(filetypefilters, QDir::Files | hidden); QMimeDatabase db; for (int i = 0 ; i < names.count() ; ++i) { QString fullpath = dir.absoluteFilePath(names.at(i)); QMimeType mime = db.mimeTypeForFile(fullpath); if ( mime.inherits("application/x-sqlite3") ) { if (enabler[SearchWorker::EnableSqlite]) wtab[SearchWorker::EnableSqlite].append(names.at(i)); } else if ( mime.inherits("application/x-desktop") ) { if (enabler[SearchWorker::EnableApps]) wtab[SearchWorker::EnableApps].append(names.at(i)); } else if ( mime.inherits("text/html") ) { if (enabler[SearchWorker::EnableHtml]) wtab[SearchWorker::EnableHtml].append(names.at(i)); } else if ( mime.inherits("text/x-csrc") || mime.inherits("application/x-shellscript") || mime.inherits("text/x-python") || mime.inherits("text/x-qml") ) { if (enabler[SearchWorker::EnableSrc]) wtab[SearchWorker::EnableSrc].append(names.at(i)); } else if ( mime.inherits("text/plain") ) { if (enabler[SearchWorker::EnableTxt]) wtab[SearchWorker::EnableTxt].append(names.at(i)); } } } return wtab; }
bool DropHandler::handleURL(const QList<QUrl>& urls_) { bool hasUnknown = false; QList<QUrl> tc, pdf, bib, ris, ciw; foreach(const QUrl& url, urls_) { QMimeType ptr; // findByURL doesn't work for http, so actually query // the url itself if(url.scheme() != QLatin1String("http")) { QMimeDatabase db; ptr = db.mimeTypeForUrl(url); } else { KIO::MimetypeJob* job = KIO::mimetype(url, KIO::HideProgressInfo); KJobWidgets::setWindow(job, GUI::Proxy::widget()); job->exec(); QMimeDatabase db; ptr = db.mimeTypeForName(job->mimetype()); } if(ptr.inherits(QLatin1String("application/x-tellico"))) { tc << url; } else if(ptr.inherits(QLatin1String("application/pdf"))) { pdf << url; } else if(ptr.inherits(QLatin1String("text/x-bibtex")) || ptr.inherits(QLatin1String("application/x-bibtex")) || ptr.inherits(QLatin1String("application/bibtex"))) { bib << url; } else if(ptr.inherits(QLatin1String("application/x-research-info-systems"))) { ris << url; } else if(url.fileName().endsWith(QLatin1String(".bib"))) { bib << url; } else if(url.fileName().endsWith(QLatin1String(".ris"))) { ris << url; } else if(url.fileName().endsWith(QLatin1String(".ciw"))) { ciw << url; } else if(ptr.inherits(QLatin1String("text/plain")) && Import::BibtexImporter::maybeBibtex(url)) { bib << url; } else if(ptr.inherits(QLatin1String("text/plain")) && Import::RISImporter::maybeRIS(url)) { ris << url; } else if(ptr.inherits(QLatin1String("text/plain")) && Import::CIWImporter::maybeCIW(url)) { ciw << url; } else { myDebug() << "unrecognized type: " << ptr.name() << " (" << url << ")"; hasUnknown = true; } }
QString uwsgiProcess::findApplication(const QDir &projectDir) { QMimeDatabase m_db; QDirIterator it(projectDir.absolutePath(), QDir::Files, QDirIterator::Subdirectories); while (it.hasNext()) { QString file = it.next(); QMimeType mime = m_db.mimeTypeForFile(file); if (mime.inherits(QStringLiteral("application/x-sharedlib"))) { return file; } } return QString(); }
void FolderFilesList::checkNextItem(const QFileInfo &item) { if (m_cancelSearch) { return; } if (item.isFile()) { if (!m_binary) { QMimeType mimeType = QMimeDatabase().mimeTypeForFile(item); if (!mimeType.inherits(QStringLiteral("text/plain"))) { return; } } m_files << item.absoluteFilePath(); } else { QDir currentDir(item.absoluteFilePath()); if (!currentDir.isReadable()) { qDebug() << currentDir.absolutePath() << "Not readable"; return; } QDir::Filters filter = QDir::Files | QDir::NoDotAndDotDot | QDir::Readable; if (m_hidden) filter |= QDir::Hidden; if (m_recursive) filter |= QDir::AllDirs; if (!m_symlinks) filter |= QDir::NoSymLinks; // sort the items to have an deterministic order! const QFileInfoList currentItems = currentDir.entryInfoList(m_types, filter, QDir::Name | QDir::LocaleAware); bool skip; for (int i = 0; i<currentItems.size(); ++i) { skip = false; for (int j=0; j<m_excludeList.size(); j++) { if (m_excludeList[j].exactMatch(currentItems[i].fileName())) { skip = true; break; } } if (!skip) { checkNextItem(currentItems[i]); } } } }
// KDE5 TODO: merge with comment()? Need to see what lxr says about the usage of both. QString KFileItem::mimeComment() const { if (!d) { return QString(); } const QString displayType = d->m_entry.stringValue(KIO::UDSEntry::UDS_DISPLAY_TYPE); if (!displayType.isEmpty()) { return displayType; } bool isLocalUrl; QUrl url = mostLocalUrl(&isLocalUrl); QMimeType mime = currentMimeType(); // This cannot move to kio_file (with UDS_DISPLAY_TYPE) because it needs // the mimetype to be determined, which is done here, and possibly delayed... if (isLocalUrl && !d->isSlow() && mime.inherits(QStringLiteral("application/x-desktop"))) { KDesktopFile cfg(url.toLocalFile()); QString comment = cfg.desktopGroup().readEntry("Comment"); if (!comment.isEmpty()) { return comment; } } // Support for .directory file in directories if (isLocalUrl && isDir() && isDirectoryMounted(url)) { QUrl u(url); u.setPath(u.path() + QLatin1String("/.directory")); const KDesktopFile cfg(u.toLocalFile()); const QString comment = cfg.readComment(); if (!comment.isEmpty()) { return comment; } } const QString comment = mime.comment(); //qDebug() << "finding comment for " << url.url() << " : " << d->m_mimeType->name(); if (!comment.isEmpty()) { return comment; } else { return mime.name(); } }
//! [5] QStringList Window::findFiles(const QStringList &files, const QString &text) { QProgressDialog progressDialog(this); progressDialog.setCancelButtonText(tr("&Cancel")); progressDialog.setRange(0, files.size()); progressDialog.setWindowTitle(tr("Find Files")); //! [5] //! [6] QMimeDatabase mimeDatabase; QStringList foundFiles; for (int i = 0; i < files.size(); ++i) { progressDialog.setValue(i); progressDialog.setLabelText( tr("Searching file number %1 of %n...", 0, files.size()).arg(i)); QCoreApplication::processEvents(); //! [6] if (progressDialog.wasCanceled()) break; //! [7] const QString fileName = files.at(i); const QMimeType mimeType = mimeDatabase.mimeTypeForFile(fileName); if (mimeType.isValid() && !mimeType.inherits(QStringLiteral("text/plain"))) { qWarning() << "Not searching binary file " << QDir::toNativeSeparators(fileName); continue; } QFile file(fileName); if (file.open(QIODevice::ReadOnly)) { QString line; QTextStream in(&file); while (!in.atEnd()) { if (progressDialog.wasCanceled()) break; line = in.readLine(); if (line.contains(text, Qt::CaseInsensitive)) { foundFiles << files[i]; break; } } } } return foundFiles; }
void WebApplication::sendFile(const QString &path) { const QDateTime lastModified {QFileInfo(path).lastModified()}; // find translated file in cache auto it = m_translatedFiles.constFind(path); if ((it != m_translatedFiles.constEnd()) && (lastModified <= (*it).lastModified)) { const QString mimeName {QMimeDatabase().mimeTypeForFileNameAndData(path, (*it).data).name()}; print((*it).data, mimeName); header(Http::HEADER_CACHE_CONTROL, getCachingInterval(mimeName)); return; } QFile file {path}; if (!file.open(QIODevice::ReadOnly)) { qDebug("File %s was not found!", qUtf8Printable(path)); throw NotFoundHTTPError(); } if (file.size() > MAX_ALLOWED_FILESIZE) { qWarning("%s: exceeded the maximum allowed file size!", qUtf8Printable(path)); throw InternalServerErrorHTTPError(tr("Exceeded the maximum allowed file size (%1)!") .arg(Utils::Misc::friendlyUnit(MAX_ALLOWED_FILESIZE))); } QByteArray data {file.readAll()}; file.close(); const QMimeType mimeType {QMimeDatabase().mimeTypeForFileNameAndData(path, data)}; const bool isTranslatable {mimeType.inherits(QLatin1String("text/plain"))}; // Translate the file if (isTranslatable) { QString dataStr {data}; translateDocument(dataStr); data = dataStr.toUtf8(); m_translatedFiles[path] = {data, lastModified}; // caching translated file } print(data, mimeType.name()); header(Http::HEADER_CACHE_CONTROL, getCachingInterval(mimeType.name())); }
bool MimeTypeChecker::isWantedItem(const Item &item, const QString &wantedMimeType) { if (wantedMimeType.isEmpty() || !item.isValid()) { return false; } const QString mimeType = item.mimeType(); if (mimeType.isEmpty()) { return false; } if (mimeType == wantedMimeType) { return true; } QMimeDatabase db; const QMimeType mt = db.mimeTypeForName(mimeType); if (!mt.isValid()) { return false; } return mt.inherits(wantedMimeType); }
ActionReply SddmAuthHelper::installtheme(const QVariantMap &args) { const QString filePath = args["filePath"].toString(); if (filePath.isEmpty()) { return ActionReply::HelperErrorReply(); } const QString themesBaseDir = QStandardPaths::locate(QStandardPaths::GenericDataLocation, "sddm/themes", QStandardPaths::LocateDirectory); QDir dir(themesBaseDir); if (!dir.exists()) { return ActionReply::HelperErrorReply(); } qDebug() << "Installing " << filePath << " into " << themesBaseDir; if (!QFile::exists(filePath)) { return ActionReply::HelperErrorReply(); } QMimeDatabase db; QMimeType mimeType = db.mimeTypeForFile(filePath); qWarning() << "Postinstallation: uncompress the file"; QScopedPointer<KArchive> archive; //there must be a better way to do this? If not, make a static bool KZip::supportsMimeType(const QMimeType &type); ? //or even a factory class in KArchive if (mimeType.inherits(QStringLiteral("application/zip"))) { archive.reset(new KZip(filePath)); } else if (mimeType.inherits(QStringLiteral("application/tar")) || mimeType.inherits(QStringLiteral("application/x-gzip")) || mimeType.inherits(QStringLiteral("application/x-bzip")) || mimeType.inherits(QStringLiteral("application/x-lzma")) || mimeType.inherits(QStringLiteral("application/x-xz")) || mimeType.inherits(QStringLiteral("application/x-bzip-compressed-tar")) || mimeType.inherits(QStringLiteral("application/x-compressed-tar"))) { archive.reset(new KTar(filePath)); } else { auto e = ActionReply::HelperErrorReply(); e.setErrorDescription(i18n("Invalid theme package")); return e; } if (!archive->open(QIODevice::ReadOnly)) { auto e = ActionReply::HelperErrorReply(); e.setErrorDescription("Could not open file"); return e; } auto directory = archive->directory(); QStringList installedPaths; //some basic validation //the top level should only have folders, and those folders should contain a valid metadata.desktop file //if we get anything else, abort everything before copying for(const QString &name: directory->entries()) { auto entry = directory->entry(name); if (!entry->isDirectory()) { auto e = ActionReply::HelperErrorReply(); e.setErrorDescription(i18n("Invalid theme package")); return e; } auto subDirectory = static_cast<const KArchiveDirectory*>(entry); auto metadataFile = subDirectory->file("metadata.desktop"); if(!metadataFile || !metadataFile->data().contains("[SddmGreeterTheme]")) { auto e = ActionReply::HelperErrorReply(); e.setErrorDescription(i18n("Invalid theme package")); return e; } installedPaths.append(themesBaseDir + '/' + name); } if (!directory->copyTo(themesBaseDir)) { auto e = ActionReply::HelperErrorReply(); e.setErrorDescription(i18n("Could not decompress archive")); return e; } auto rc = ActionReply::SuccessReply(); rc.addData(QStringLiteral("installedPaths"), installedPaths); return rc; }
bool Document::open( const QString &fileName ) { close(); QMimeDatabase db; const QMimeType mime = db.mimeTypeForFile(fileName, QMimeDatabase::MatchContent); /** * We have a zip archive */ if ( mime.inherits(QStringLiteral("application/x-cbz") ) || mime.inherits( QStringLiteral("application/zip") ) ) { mArchive = new KZip( fileName ); if ( !processArchive() ) { return false; } /** * We have a TAR archive */ } else if ( mime.inherits( QStringLiteral("application/x-cbt") ) || mime.inherits( QStringLiteral("application/x-gzip") ) || mime.inherits( QStringLiteral("application/x-tar") ) || mime.inherits( QStringLiteral("application/x-bzip") ) ) { mArchive = new KTar( fileName ); if ( !processArchive() ) { return false; } } else if ( mime.inherits( QStringLiteral("application/x-cbr") ) || mime.inherits( QStringLiteral("application/x-rar") ) || mime.inherits( QStringLiteral("application/vnd.rar") ) ) { if ( !Unrar::isAvailable() ) { mLastErrorString = i18n( "Cannot open document, unrar was not found." ); return false; } if ( !Unrar::isSuitableVersionAvailable() ) { mLastErrorString = i18n( "The version of unrar on your system is not suitable for opening comicbooks." ); return false; } /** * We have a rar archive */ mUnrar = new Unrar(); if ( !mUnrar->open( fileName ) ) { delete mUnrar; mUnrar = 0; return false; } mEntries = mUnrar->list(); } else if ( mime.inherits( QStringLiteral("inode/directory") ) ) { mDirectory = new Directory(); if ( !mDirectory->open( fileName ) ) { delete mDirectory; mDirectory = 0; return false; } mEntries = mDirectory->list(); } else { mLastErrorString = i18n( "Unknown ComicBook format." ); return false; } return true; }
// Only called when a filename was given bool KTar::createDevice(QIODevice::OpenMode mode) { if (d->mimetype.isEmpty()) { // Find out mimetype manually QMimeDatabase db; QMimeType mime; if (mode != QIODevice::WriteOnly && QFile::exists(fileName())) { // Give priority to file contents: if someone renames a .tar.bz2 to .tar.gz, // we can still do the right thing here. QFile f(fileName()); if (f.open(QIODevice::ReadOnly)) { mime = db.mimeTypeForData(&f); } if (!mime.isValid()) { // Unable to determine mimetype from contents, get it from file name mime = db.mimeTypeForFile(fileName(), QMimeDatabase::MatchExtension); } } else { mime = db.mimeTypeForFile(fileName(), QMimeDatabase::MatchExtension); } //qDebug() << mode << mime->name(); if (mime.inherits(QString::fromLatin1("application/x-compressed-tar")) || mime.inherits(QString::fromLatin1(application_gzip))) { // gzipped tar file (with possibly invalid file name), ask for gzip filter d->mimetype = QString::fromLatin1(application_gzip); } else if (mime.inherits(QString::fromLatin1("application/x-bzip-compressed-tar")) || mime.inherits(QString::fromLatin1(application_bzip))) { // bzipped2 tar file (with possibly invalid file name), ask for bz2 filter d->mimetype = QString::fromLatin1(application_bzip); } else if (mime.inherits(QString::fromLatin1("application/x-lzma-compressed-tar")) || mime.inherits(QString::fromLatin1(application_lzma))) { // lzma compressed tar file (with possibly invalid file name), ask for xz filter d->mimetype = QString::fromLatin1(application_lzma); } else if (mime.inherits(QString::fromLatin1("application/x-xz-compressed-tar")) || mime.inherits(QString::fromLatin1(application_xz))) { // xz compressed tar file (with possibly invalid name), ask for xz filter d->mimetype = QString::fromLatin1(application_xz); } } if (d->mimetype == QLatin1String("application/x-tar")) { return KArchive::createDevice(mode); } else if (mode == QIODevice::WriteOnly) { if (!KArchive::createDevice(mode)) return false; if (!d->mimetype.isEmpty()) { // Create a compression filter on top of the QSaveFile device that KArchive created. //qDebug() << "creating KFilterDev for" << d->mimetype; KCompressionDevice::CompressionType type = KFilterDev::compressionTypeForMimeType(d->mimetype); KCompressionDevice* compressionDevice = new KCompressionDevice(device(), true, type); setDevice(compressionDevice); } return true; } else { // The compression filters are very slow with random access. // So instead of applying the filter to the device, // the file is completely extracted instead, // and we work on the extracted tar file. // This improves the extraction speed by the tar ioslave dramatically, // if the archive file contains many files. // This is because the tar ioslave extracts one file after the other and normally // has to walk through the decompression filter each time. // Which is in fact nearly as slow as a complete decompression for each file. Q_ASSERT(!d->tmpFile); d->tmpFile = new QTemporaryFile(); d->tmpFile->setFileTemplate(QLatin1String("ktar-XXXXXX.tar")); d->tmpFile->open(); //qDebug() << "creating tempfile:" << d->tmpFile->fileName(); setDevice(d->tmpFile); return true; } }
bool PackageJobThread::installPackage(const QString &src, const QString &dest, OperationType operation) { QDir root(dest); if (!root.exists()) { QDir().mkpath(dest); if (!root.exists()) { d->errorMessage = i18n("Could not create package root directory: %1", dest); d->errorCode = Package::JobError::RootCreationError; //qWarning() << "Could not create package root directory: " << dest; return false; } } QFileInfo fileInfo(src); if (!fileInfo.exists()) { d->errorMessage = i18n("No such file: %1", src); d->errorCode = Package::JobError::PackageFileNotFoundError; return false; } QString path; QTemporaryDir tempdir; bool archivedPackage = false; if (fileInfo.isDir()) { // we have a directory, so let's just install what is in there path = src; // make sure we end in a slash! if (!path.endsWith('/')) { path.append('/'); } } else { KArchive *archive = 0; QMimeDatabase db; QMimeType mimetype = db.mimeTypeForFile(src); if (mimetype.inherits(QStringLiteral("application/zip"))) { archive = new KZip(src); } else if (mimetype.inherits(QStringLiteral("application/x-compressed-tar")) || mimetype.inherits(QStringLiteral("application/x-tar")) || mimetype.inherits(QStringLiteral("application/x-bzip-compressed-tar")) || mimetype.inherits(QStringLiteral("application/x-xz")) || mimetype.inherits(QStringLiteral("application/x-lzma"))) { archive = new KTar(src); } else { //qWarning() << "Could not open package file, unsupported archive format:" << src << mimetype.name(); d->errorMessage = i18n("Could not open package file, unsupported archive format: %1 %2", src, mimetype.name()); d->errorCode = Package::JobError::UnsupportedArchiveFormatError; return false; } if (!archive->open(QIODevice::ReadOnly)) { //qWarning() << "Could not open package file:" << src; delete archive; d->errorMessage = i18n("Could not open package file: %1", src); d->errorCode = Package::JobError::PackageOpenError; return false; } archivedPackage = true; path = tempdir.path() + '/'; d->installPath = path; const KArchiveDirectory *source = archive->directory(); source->copyTo(path); QStringList entries = source->entries(); if (entries.count() == 1) { const KArchiveEntry *entry = source->entry(entries[0]); if (entry->isDirectory()) { path.append(entry->name()).append("/"); } } delete archive; } QDir packageDir(path); QFileInfoList entries = packageDir.entryInfoList(*metaDataFiles); KPluginMetaData meta; if (!entries.isEmpty()) { const QString metadataFilePath = entries.first().filePath(); if (metadataFilePath.endsWith(QLatin1String(".desktop"))) meta = KPluginMetaData(metadataFilePath); else { QFile f(metadataFilePath); if(!f.open(QIODevice::ReadOnly)){ qWarning() << "Couldn't open metadata file" << src << path; d->errorMessage = i18n("Could not open metadata file: %1", src); d->errorCode = Package::JobError::MetadataFileMissingError; return false; } QJsonObject metadataObject = QJsonDocument::fromJson(f.readAll()).object(); meta = KPluginMetaData(metadataObject, QString(), metadataFilePath); } } if (!meta.isValid()) { qDebug() << "No metadata file in package" << src << path; d->errorMessage = i18n("No metadata file in package: %1", src); d->errorCode = Package::JobError::MetadataFileMissingError; return false; } QString pluginName = meta.pluginId(); qDebug() << "pluginname: " << meta.pluginId(); if (pluginName.isEmpty()) { //qWarning() << "Package plugin name not specified"; d->errorMessage = i18n("Package plugin name not specified: %1", src); d->errorCode = Package::JobError::PluginNameMissingError; return false; } // Ensure that package names are safe so package uninstall can't inject // bad characters into the paths used for removal. QRegExp validatePluginName("^[\\w-\\.]+$"); // Only allow letters, numbers, underscore and period. if (!validatePluginName.exactMatch(pluginName)) { //qDebug() << "Package plugin name " << pluginName << "contains invalid characters"; d->errorMessage = i18n("Package plugin name %1 contains invalid characters", pluginName); d->errorCode = Package::JobError::PluginNameInvalidError; return false; } QString targetName = dest; if (targetName[targetName.size() - 1] != '/') { targetName.append('/'); } targetName.append(pluginName); if (QFile::exists(targetName)) { if (operation == Update) { KPluginMetaData oldMeta(targetName + QLatin1String("/metadata.desktop")); if (oldMeta.serviceTypes() != meta.serviceTypes()) { d->errorMessage = i18n("The new package has a different type from the old version already installed.", meta.version(), meta.pluginId(), oldMeta.version()); d->errorCode = Package::JobError::UpdatePackageTypeMismatchError; } else if (isVersionNewer(oldMeta.version(), meta.version())) { const bool ok = uninstallPackage(targetName); if (!ok) { d->errorMessage = i18n("Impossible to remove the old installation of %1 located at %2. error: %3", pluginName, targetName, d->errorMessage); d->errorCode = Package::JobError::OldVersionRemovalError; } } else { d->errorMessage = i18n("Not installing version %1 of %2. Version %3 already installed.", meta.version(), meta.pluginId(), oldMeta.version()); d->errorCode = Package::JobError::NewerVersionAlreadyInstalledError; } } else { d->errorMessage = i18n("%1 already exists", targetName); d->errorCode = Package::JobError::PackageAlreadyInstalledError; } if (d->errorCode != KJob::NoError) { d->installPath = targetName; return false; } } //install dependencies const QStringList dependencies = KPluginMetaData::readStringList(meta.rawData(), QStringLiteral("X-KPackage-Dependencies")); for(const QString &dep : dependencies) { QUrl depUrl(dep); if (!installDependency(depUrl)) { d->errorMessage = i18n("Could not install dependency: %1", dep); d->errorCode = Package::JobError::PackageCopyError; return false; } } if (archivedPackage) { // it's in a temp dir, so just move it over. const bool ok = copyFolder(path, targetName); removeFolder(path); if (!ok) { //qWarning() << "Could not move package to destination:" << targetName; d->errorMessage = i18n("Could not move package to destination: %1", targetName); d->errorCode = Package::JobError::PackageMoveError; return false; } } else { // it's a directory containing the stuff, so copy the contents rather // than move them const bool ok = copyFolder(path, targetName); if (!ok) { //qWarning() << "Could not copy package to destination:" << targetName; d->errorMessage = i18n("Could not copy package to destination: %1", targetName); d->errorCode = Package::JobError::PackageCopyError; return false; } } if (archivedPackage) { // no need to remove the temp dir (which has been successfully moved if it's an archive) tempdir.setAutoRemove(false); } indexDirectory(dest, QStringLiteral("kpluginindex.json")); d->installPath = targetName; //qWarning() << "Not updating kbuildsycoca4, since that will go away. Do it yourself for now if needed."; return true; }