00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #include <iostream>
00021
00022 #include <QDir>
00023 #include <QDBusInterface>
00024
00025 #include <KApplication>
00026 #include <KAboutData>
00027 #include <KAction>
00028 #include <KCmdLineArgs>
00029 #include <KLocale>
00030 #include <KService>
00031 #include <KServiceTypeTrader>
00032 #include <KShell>
00033 #include <KStandardDirs>
00034 #include <KProcess>
00035 #include <KSycoca>
00036 #include <KConfigGroup>
00037
00038 #include <Plasma/PackageStructure>
00039 #include <Plasma/Package>
00040 #include <Plasma/PackageMetadata>
00041
00042 static const char description[] = I18N_NOOP("Install, list, remove Plasma packages");
00043 static const char version[] = "0.1";
00044
00045 void output(const QString &msg)
00046 {
00047 std::cout << msg.toLocal8Bit().constData() << std::endl;
00048 }
00049
00050 void runKbuildsycoca()
00051 {
00052 QDBusInterface dbus("org.kde.kded", "/kbuildsycoca", "org.kde.kbuildsycoca");
00053 dbus.call(QDBus::Block, "recreate");
00054 }
00055
00056 QStringList packages(const QString& type)
00057 {
00058 QStringList result;
00059 KService::List services = KServiceTypeTrader::self()->query("Plasma/" + type);
00060 foreach(const KService::Ptr &service, services) {
00061 result << service->property("X-KDE-PluginInfo-Name", QVariant::String).toString();
00062 }
00063 return result;
00064 }
00065
00066 void listPackages(const QString& type)
00067 {
00068 QStringList list = packages(type);
00069 list.sort();
00070 foreach(const QString& package, list) {
00071 output(package);
00072 }
00073 }
00074
00075 int main(int argc, char **argv)
00076 {
00077 KAboutData aboutData("plasmapkg", 0, ki18n("Plasma Package Manager"),
00078 version, ki18n(description), KAboutData::License_GPL,
00079 ki18n("(C) 2008, Aaron Seigo"));
00080 aboutData.addAuthor( ki18n("Aaron Seigo"),
00081 ki18n("Original author"),
00082 "aseigo@kde.org" );
00083
00084 KComponentData componentData(aboutData);
00085
00086 KCmdLineArgs::init( argc, argv, &aboutData );
00087
00088 KCmdLineOptions options;
00089 options.add("g");
00090 options.add("global", ki18n("For install or remove, operates on packages installed for all users."));
00091 options.add("t");
00092 options.add("type <type>",
00093 ki18nc("theme, wallpaper, etc. are keywords, but they may be translated, as both versions "
00094 "are recognized by the application "
00095 "(if translated, should be same as messages with 'package type' context below)",
00096 "The type of package, e.g. theme, wallpaper, plasmoid, dataengine, runner, etc."),
00097 "plasmoid");
00098 options.add("s");
00099 options.add("i");
00100 options.add("install <path>", ki18nc("Do not translate <path>", "Install the package at <path>"));
00101 options.add("u");
00102 options.add("upgrade <path>", ki18nc("Do not translate <path>", "Upgrade the package at <path>"));
00103 options.add("l");
00104 options.add("list", ki18n("List installed packages"));
00105 options.add("r");
00106 options.add("remove <name>", ki18nc("Do not translate <name>", "Remove the package named <name>"));
00107 options.add("p");
00108 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."));
00109 KCmdLineArgs::addCmdLineOptions( options );
00110
00111 KApplication app;
00112
00113 KCmdLineArgs *args = KCmdLineArgs::parsedArgs();
00114 const QString type = args->getOption("type").toLower();
00115 QString packageRoot = type;
00116 QString servicePrefix;
00117 QString pluginType;
00118 Plasma::PackageStructure *installer = 0;
00119
00120 if (type == i18nc("package type", "plasmoid") || type == "plasmoid") {
00121 packageRoot = "plasma/plasmoids/";
00122 servicePrefix = "plasma-applet-";
00123 pluginType = "Applet";
00124 } else if (type == i18nc("package type", "theme") || type == "theme") {
00125 packageRoot = "desktoptheme/";
00126 } else if (type == i18nc("package type", "wallpaper") || type == "wallpaper") {
00127 packageRoot = "wallpapers/";
00128 } else if (type == i18nc("package type", "dataengine") || type == "dataengine") {
00129 packageRoot = "plasma/dataengines/";
00130 servicePrefix = "plasma-dataengine-";
00131 pluginType = "DataEngine";
00132 } else if (type == i18nc("package type", "runner") || type == "runner") {
00133 packageRoot = "plasma/runners/";
00134 servicePrefix = "plasma-runner-";
00135 pluginType = "Runner";
00136 } else {
00137 QString constraint = QString("'%1' == [X-KDE-PluginInfo-Name]").arg(packageRoot);
00138 KService::List offers = KServiceTypeTrader::self()->query("Plasma/PackageStructure", constraint);
00139 if (offers.isEmpty()) {
00140 output(i18n("Could not find a suitable installer for package of type %1", type));
00141 return 1;
00142 }
00143
00144 KService::Ptr offer = offers.first();
00145 QString error;
00146 installer = offer->createInstance<Plasma::PackageStructure>(0, QVariantList(), &error);
00147
00148 if (!installer) {
00149 output(i18n("Could not load installer for package of type %1. Error reported was: %2",
00150 type, error));
00151 return 1;
00152 }
00153 packageRoot = installer->defaultPackageRoot();
00154 pluginType = installer->type();
00155 }
00156
00157 if (args->isSet("list")) {
00158 listPackages(pluginType);
00159 } else {
00160
00161 if (!installer) {
00162 installer = new Plasma::PackageStructure();
00163 installer->setServicePrefix(servicePrefix);
00164 }
00165
00166 if (args->isSet("packageroot")) {
00167 packageRoot = args->getOption("packageroot");
00168 } else if (args->isSet("global")) {
00169 packageRoot = KStandardDirs::locate("data", packageRoot);
00170 } else {
00171 packageRoot = KStandardDirs::locateLocal("data", packageRoot);
00172 }
00173
00174 QString package;
00175 QString packageFile;
00176 if (args->isSet("remove")) {
00177 package = args->getOption("remove");
00178 } else if (args->isSet("upgrade")) {
00179 package = args->getOption("upgrade");
00180 } else if (args->isSet("install")) {
00181 package = args->getOption("install");
00182 }
00183 if (!QDir::isAbsolutePath(package)) {
00184 packageFile = QDir(QDir::currentPath() + '/' + package).absolutePath();
00185 } else {
00186 packageFile = package;
00187 }
00188
00189 if (args->isSet("remove") || args->isSet("upgrade")) {
00190 installer->setPath(packageFile);
00191 Plasma::PackageMetadata metadata = installer->metadata();
00192
00193 QString pluginName;
00194 if (metadata.pluginName().isEmpty()) {
00195
00196 pluginName = package;
00197 } else {
00198
00199 pluginName = metadata.pluginName();
00200 }
00201
00202 QStringList installed = packages(pluginType);
00203 if (installed.contains(pluginName)) {
00204 if (installer->uninstallPackage(pluginName, packageRoot)) {
00205 output(i18n("Successfully removed %1", pluginName));
00206 } else if (!args->isSet("upgrade")) {
00207 output(i18n("Removal of %1 failed.", pluginName));
00208 return 1;
00209 }
00210 } else {
00211 output(i18n("Plugin %1 is not installed.", pluginName));
00212 }
00213 }
00214 if (args->isSet("install") || args->isSet("upgrade")) {
00215 if (installer->installPackage(packageFile, packageRoot)) {
00216 output(i18n("Successfully installed %1", packageFile));
00217 } else {
00218 output(i18n("Installation of %1 failed.", packageFile));
00219 return 1;
00220 }
00221 }
00222 if (package.isEmpty()) {
00223 KCmdLineArgs::usageError(i18nc("No option was given, this is the error message telling the user he needs at least one, do not translate install, remove, upgrade nor list", "One of install, remove, upgrade or list is required."));
00224 } else {
00225 runKbuildsycoca();
00226 }
00227 }
00228 return 0;
00229 }
00230