コード例 #1
0
void CatalogBuilder::buildCatalog()
{
	progress = CATALOG_PROGRESS_MIN;
	emit catalogIncrement(progress);
	catalog->incrementTimestamp();
    indexed.clear();

	QList<Directory> memDirs = SettingsManager::readCatalogDirectories();
	QHash<uint, PluginInfo> pluginsInfo = plugins->getPlugins();
	totalItems = memDirs.count() + pluginsInfo.count();
    currentItem = 0;

	while (currentItem < memDirs.count())
    {
		QString cur = platform->expandEnvironmentVars(memDirs[currentItem].name);
		indexDirectory(cur, memDirs[currentItem].types, memDirs[currentItem].indexDirs, memDirs[currentItem].indexExe, memDirs[currentItem].depth);
        progressStep(currentItem);
	}

	// Don't call the pluginhandler to request catalog because we need to track progress
	plugins->getCatalogs(catalog, this);

	catalog->purgeOldItems();
	indexed.clear();
	progress = CATALOG_PROGRESS_MAX;
    emit catalogFinished();
}
コード例 #2
0
ファイル: FileIndex.cpp プロジェクト: darkf/openrw
void FileIndex::indexTree(const std::string& root)
{
	indexDirectory(root);
	
	DIR* dp = opendir(root.c_str());
	dirent* ep;
	if ( dp == NULL ) {
		throw std::runtime_error("Unable to open directory: " + root);
	}
	while( (ep = readdir(dp)) )
	{
		std::string filepath = root +"/"+ ep->d_name;

		bool isDirectory = false;
		if (ep->d_type != DT_UNKNOWN) {
			isDirectory = ep->d_type == DT_DIR;
		} else {
			struct stat filedata;
			if (stat(filepath.c_str(), &filedata) == 0) {
				isDirectory = S_ISDIR(filedata.st_mode);
			}
		}

		if (isDirectory && ep->d_name[0] != '.') {
			indexTree(filepath);
		}
	}
	closedir(dp);
}
コード例 #3
0
ファイル: packagejobthread.cpp プロジェクト: KDE/kpackage
bool PackageJobThread::uninstallPackage(const QString &packagePath)
{
    if (!QFile::exists(packagePath)) {
        d->errorMessage = i18n("%1 does not exist", packagePath);
        d->errorCode = Package::JobError::PackageFileNotFoundError;
        return false;
    }
    QString pkg;
    QString root;
    {
        // FIXME: remove, pass in packageroot, type and pluginName separately?
        QStringList ps = packagePath.split('/');
        int ix = ps.count() - 1;
        if (packagePath.endsWith('/')) {
            ix = ps.count() - 2;
        }
        pkg = ps[ix];
        ps.pop_back();
        root = ps.join('/');
    }

    bool ok = removeFolder(packagePath);
    if (!ok) {
        d->errorMessage = i18n("Could not delete package from: %1", packagePath);
        d->errorCode = Package::JobError::PackageUninstallError;
        return false;
    }

    indexDirectory(root, QStringLiteral("kpluginindex.json"));

    return true;
}
コード例 #4
0
ファイル: FileIndexer.cpp プロジェクト: OTTeam/CaptainAdhoc
qint32 FileIndexer::updateDatabase()
{
    qint32 count = 0;
    qDebug() << "Indexing " << _directories.size() << " directories";
    foreach (QDir dir, _directories) {
        count += indexDirectory(dir);
    }
コード例 #5
0
void CatalogBuilder::indexDirectory(const QString& directory, const QStringList& filters, bool fdirs, bool fbin, int depth)
{
	QString dir = QDir::toNativeSeparators(directory);
	QDir qd(dir);
	dir = qd.absolutePath();
	QStringList dirs = qd.entryList(QDir::AllDirs);

	if (depth > 0)
	{
		for (int i = 0; i < dirs.count(); ++i)
		{
			if (!dirs[i].startsWith("."))
			{
				QString cur = dirs[i];
				if (!cur.contains(".lnk"))
				{
#ifdef Q_WS_MAC
                                    // Special handling of app directories
                                    if (cur.endsWith(".app", Qt::CaseInsensitive)) {
                                        CatItem item(dir + "/" + cur);
                                        platform->alterItem(&item);
                                        catalog->addItem(item);
                                    }
                                    else
#endif

                    // Sleep shoud be here :)
                    CanIHazSleep::msleep(10);
					indexDirectory(dir + "/" + dirs[i], filters, fdirs, fbin, depth-1);
				}
			}
		}
	}

	if (fdirs)
	{
		for (int i = 0; i < dirs.count(); ++i)
		{
			if (!dirs[i].startsWith(".") && !indexed.contains(dir + "/" + dirs[i]))
			{
				bool isShortcut = dirs[i].endsWith(".lnk", Qt::CaseInsensitive);

				CatItem item(dir + "/" + dirs[i], !isShortcut);
				catalog->addItem(item);
				indexed.insert(dir + "/" + dirs[i]);
			}
		}
	}
	else
	{
		// Grab any shortcut directories 
		// This is to work around a QT weirdness that treats shortcuts to directories as actual directories
		for (int i = 0; i < dirs.count(); ++i)
		{
			if (!dirs[i].startsWith(".") && dirs[i].endsWith(".lnk",Qt::CaseInsensitive))
			{
				if (!indexed.contains(dir + "/" + dirs[i]))
				{
					CatItem item(dir + "/" + dirs[i], true);
					catalog->addItem(item);
					indexed.insert(dir + "/" + dirs[i]);
				}
			}
		}
	}

	if (fbin)
	{
		QStringList bins = qd.entryList(QDir::Files | QDir::Executable);
		for (int i = 0; i < bins.count(); ++i)
		{
			if (!indexed.contains(dir + "/" + bins[i]))
			{
				CatItem item(dir + "/" + bins[i]);
				catalog->addItem(item);
				indexed.insert(dir + "/" + bins[i]);
			}
		}
	}

	// Don't want a null file filter, that matches everything..
	if (filters.count() == 0)
		return;

	QStringList files = qd.entryList(filters, QDir::Files | QDir::System, QDir::Unsorted );
	for (int i = 0; i < files.count(); ++i)
	{
		if (!indexed.contains(dir + "/" + files[i]))
		{
			CatItem item(dir + "/" + files[i]);
			platform->alterItem(&item);
#ifdef Q_WS_X11
                        if(item.fullPath.endsWith(".desktop") && item.icon == "")
                            continue;
#endif
			catalog->addItem(item);

			indexed.insert(dir + "/" + files[i]);
		}
	}
}
コード例 #6
0
ファイル: packagejobthread.cpp プロジェクト: KDE/kpackage
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;
}