On Thursday 30 October 2008 15:11:15 Aaron J. Seigo wrote:
> On Thursday 30 October 2008, Petri Damstén wrote:
> > It gets installed packages before and after install to get installed
> > package name(s). It then saves them to config so on uninstall we can get
> > the name of the package for the package file.
>
> package files are guaranteed to be unique in name (so i'm not sure it's
> reliable?), 

For GHNS they should be unique (kde-files.org adds an id to the file name) and 
I modified the patch so that remove fails if we found more than one package.

> and if we wish to keep this information somewhere it should be
> in the installed .desktop file.

Do you mean like this?

Petri

Index: package.h
===================================================================
--- package.h	(revision 877358)
+++ package.h	(working copy)
@@ -152,7 +152,8 @@
          * @arg the full path to the desktop file (must be KPluginInfo compatible)
          * @return true on success, false on failure
          */
-        static bool registerPackage(const PackageMetadata &data, const QString &iconPath);
+        static bool registerPackage(const PackageMetadata &data, const QString &iconPath,
+                                    const QString &packageFile = QString());
 
         /**
          * Creates a package based on the metadata from the files contained
Index: servicetypes/plasma-applet.desktop
===================================================================
--- servicetypes/plasma-applet.desktop	(revision 877358)
+++ servicetypes/plasma-applet.desktop	(working copy)
@@ -71,3 +71,5 @@
 [PropertyDef::X-Plasma-DropMimeTypes]
 Type=QStringList
 
+[PropertyDef::X-Plasma-PackageFile]
+Type=QString
Index: package.cpp
===================================================================
--- package.cpp	(revision 877358)
+++ package.cpp	(working copy)
@@ -339,17 +339,17 @@
     QString service = KStandardDirs::locateLocal("services", serviceName + ".desktop");
     KIO::FileCopyJob *job = KIO::file_copy(metaPath, service, -1, KIO::HideProgressInfo);
     if (job->exec()) {
+        KDesktopFile df(service);
+        KConfigGroup cg = df.desktopGroup();
         // the icon in the installed file needs to point to the icon in the
         // installation dir!
         QString iconPath = targetName + '/' + cg.readEntry("Icon");
         QFile icon(iconPath);
         if (icon.exists()) {
-            KDesktopFile df(service);
-            KConfigGroup cg = df.desktopGroup();
             cg.writeEntry("Icon", iconPath);
         }
+        cg.writeEntry("X-Plasma-PackageFile", package);
     }
-
     return true;
 }
 
@@ -386,7 +386,7 @@
     return true;
 }
 
-bool Package::registerPackage(const PackageMetadata &data, const QString &iconPath)
+bool Package::registerPackage(const PackageMetadata &data, const QString &iconPath, const QString &packageFile)
 {
     QString serviceName("plasma-applet-" + data.pluginName());
     QString service = KStandardDirs::locateLocal("services", serviceName + ".desktop");
@@ -411,6 +411,9 @@
         QString installedIcon("plasma_applet_" + data.pluginName() +
                               iconPath.right(iconPath.length() - iconPath.lastIndexOf("/")));
         cg.writeEntry("Icon", installedIcon);
+        if (!packageFile.isEmpty()) {
+            cg.writeEntry("X-Plasma-PackageFile", packageFile);
+        }
         installedIcon = KStandardDirs::locateLocal("icon", installedIcon);
         KIO::FileCopyJob *job = KIO::file_copy(iconPath, installedIcon, -1, KIO::HideProgressInfo);
         job->exec();
/*
 * Copyright 2008 Aaron Seigo <[EMAIL PROTECTED]>
 *
 *   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 2,
 *   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 Library General Public
 *   License along with this program; if not, write to the
 *   Free Software Foundation, Inc.,
 *   51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
 */

#include <iostream>

#include <QDir>
#include <QDBusInterface>

#include <KApplication>
#include <KAboutData>
#include <KAction>
#include <KCmdLineArgs>
#include <KLocale>
#include <KService>
#include <KServiceTypeTrader>
#include <KShell>
#include <KStandardDirs>
#include <KProcess>
#include <KSycoca>
#include <KConfigGroup>

#include <plasma/packagestructure.h>

static const char description[] = I18N_NOOP("Install, list, remove Plasma packages");
static const char version[] = "0.1";

void output(const QString &msg)
{
    std::cout << msg.toLocal8Bit().constData() << std::endl;
}

void runKbuildsycoca()
{
    QDBusInterface dbus("org.kde.kded", "/kbuildsycoca", "org.kde.kbuildsycoca");
    dbus.call(QDBus::NoBlock, "recreate");
    // To re-open database
    delete KSycoca::self();

    // Personal hack
    /*
    QString bin = KStandardDirs::findExe("kbuildsycoca4");
    if (!bin.isEmpty()) {
        KProcess process;
        process.setProgram(bin);
        process.setOutputChannelMode(KProcess::SeparateChannels);
        process.execute();
    }
    */
}

QStringList removeStrings(const QStringList& list, const QStringList& remove)
{
    QStringList result = list;
    foreach (const QString &s, remove) {
        result.removeAll(s);
    }
    return result;
}

QStringList packages(const QString& type, const QString& packageFile = QString())
{
    QStringList result;
    QString constraint;
    if (!packageFile.isEmpty()) {
        constraint = QString("[X-Plasma-PackageFile] == '%1'").arg(packageFile);
    }
    KService::List services = KServiceTypeTrader::self()->query("Plasma/" + type, constraint);
    foreach(const KService::Ptr &service, services) {
        result << service->property("X-KDE-PluginInfo-Name", QVariant::String).toString();
    }
    return result;
}

void listPackages(const QString& type)
{
    foreach(const QString& package, packages(type)) {
        output(package);
    }
}

int main(int argc, char **argv)
{
    KAboutData aboutData("plasmapkg", 0, ki18n("Plasma Package Manager"),
                         version, ki18n(description), KAboutData::License_GPL,
                         ki18n("(C) 2008, Aaron Seigo"));
    aboutData.addAuthor( ki18n("Aaron Seigo"),
                         ki18n("Original author"),
                        "[EMAIL PROTECTED]" );

    KComponentData componentData(aboutData);

    KCmdLineArgs::init( argc, argv, &aboutData );

    KCmdLineOptions options;
    options.add("g");
    options.add("global", ki18n("For install or remove, operates on packages installed for all users."));
    options.add("t");
    options.add("type <type>",
                ki18n("The type of package, e.g. theme, wallpaper, plasmoid, DataEngine, Runner, etc."),
                "plasmoid");
    options.add("s");
    options.add("i");
    options.add("install <path>", ki18n("Install the package at <path>"));
    options.add("u");
    options.add("upgrade <path>", ki18n("Upgrade the package at <path>"));
    options.add("l");
    options.add("list", ki18n("List installed packages"));
    options.add("r");
    options.add("remove <name>", ki18n("Remove the package named <name>"));
    options.add("p");
    options.add("packageroot <path>", ki18n("Absolute path to the package root. If not supplied, then the standard data directories for this KDE session will be searched instead."));
    KCmdLineArgs::addCmdLineOptions( options );

    KApplication app;

    KCmdLineArgs *args = KCmdLineArgs::parsedArgs();
    const QString type = args->getOption("type").toLower();
    QString packageRoot = type;
    QString servicePrefix;
    QString pluginType;
    Plasma::PackageStructure *installer = 0;

    if (type == i18n("plasmoid") || type == "plasmoid") {
        packageRoot = "plasma/plasmoids/";
        servicePrefix = "plasma-applet-";
        pluginType = "Applet";
    } else if (type == i18n("theme") || type == "theme") {
        packageRoot = "desktoptheme/";
    } else if (type == i18n("wallpaper") || type == "wallpaper") {
        packageRoot = "wallpapers/";
    } else if (type == i18n("dataengine") || type == "dataengine") {
        packageRoot = "plasma/dataengines/";
        servicePrefix = "plasma-dataengine-";
        pluginType = "DataEngine";
    } else if (type == i18n("runner") || type == "runner") {
        packageRoot = "plasma/runners/";
        servicePrefix = "plasma-runner-";
        pluginType = "Runner";
    } else {
        QString constraint = QString("'%1' == [X-KDE-PluginInfo-Name]").arg(packageRoot);
        KService::List offers = KServiceTypeTrader::self()->query("Plasma/PackageStructure", constraint);
        if (offers.isEmpty()) {
            output(i18n("Could not find a suitable installer for package of type %1", type));
            return 1;
        }

        KService::Ptr offer = offers.first();
        QString error;
        installer = offer->createInstance<Plasma::PackageStructure>(0, QVariantList(), &error);

        if (!installer) {
            output(i18n("Could not load installer for package of type %1. Error reported was: %2",
                        type, error));
            return 1;
        }
        packageRoot = installer->defaultPackageRoot();
        pluginType = installer->type();
    }

    if (args->isSet("list")) {
        listPackages(pluginType);
    } else {
        // install, remove or upgrade
        if (!installer) {
            installer = new Plasma::PackageStructure();
            installer->setServicePrefix(servicePrefix);
        }

        if (args->isSet("packageroot")) {
            packageRoot = args->getOption("packageroot");
        } else if (args->isSet("global")) {
            packageRoot = KStandardDirs::locate("data", packageRoot);
        } else {
            packageRoot = KStandardDirs::locateLocal("data", packageRoot);
        }

        QString package;
        QString packageFile;
        if (args->isSet("remove")) {
            package = args->getOption("remove");
        } else if (args->isSet("upgrade")) {
            package = args->getOption("upgrade");
        } else if (args->isSet("install")) {
            package = args->getOption("install");
        }
        if (!QDir::isAbsolutePath(package)) {
            packageFile = QDir(QDir::currentPath() + '/' + package).absolutePath();
        } else {
            packageFile = package;
        }

        if (args->isSet("remove") || args->isSet("upgrade")) {
            QStringList installedPackages = packages(pluginType, packageFile);
            if (installedPackages.count() > 1) {
                output(i18n("Found more than one package for %1. Unable to remove.", packageFile));
                return 1;
            }
            if (installedPackages.isEmpty()) {
                // It was not a package file
                installedPackages << package;
            }
            if (installer->uninstallPackage(installedPackages[0], packageRoot)) {
                output(i18n("Successfully removed %1", installedPackages[0]));
                runKbuildsycoca();
            } else if (!args->isSet("upgrade")) {
                output(i18n("Removal of %1 failed.", installedPackages[0]));
                return 1;
            }
        }
        if (args->isSet("install") || args->isSet("upgrade")) {
            QStringList oldPackages = packages(pluginType);
            if (installer->installPackage(packageFile, packageRoot)) {
                output(i18n("Successfully installed %1", packageFile));
                runKbuildsycoca();
            } else {
                output(i18n("Installation of %1 failed.", packageFile));
                return 1;
            }
        }
        if (package.isEmpty()) {
            KCmdLineArgs::usageError(i18n("One of install, remove, upgrade or list is required."));
        }
    }
    return 0;
}

Attachment: signature.asc
Description: This is a digitally signed message part.

_______________________________________________
Plasma-devel mailing list
Plasma-devel@kde.org
https://mail.kde.org/mailman/listinfo/plasma-devel

Reply via email to