File indexing completed on 2023-09-24 04:14:57

0001 /*
0002     SPDX-FileCopyrightText: 2007 Aaron Seigo <aseigo@kde.org>
0003     SPDX-FileCopyrightText: 2010 Marco Martin <notmart@gmail.com>
0004     SPDX-FileCopyrightText: 2010 Kevin Ottens <ervin@kde.org>
0005     SPDX-FileCopyrightText: 2009 Rob Scheepmaker
0006 
0007     SPDX-License-Identifier: LGPL-2.0-or-later
0008 */
0009 
0010 #include "package.h"
0011 
0012 #include <QTemporaryDir>
0013 
0014 #include <KArchive>
0015 #include <KDesktopFile>
0016 #include <KJob>
0017 #include <KTar>
0018 #include <QDebug>
0019 #include <kzip.h>
0020 
0021 #include "config-plasma.h"
0022 
0023 #include <QMimeDatabase>
0024 #include <QStandardPaths>
0025 
0026 #include "packagestructure.h"
0027 #include "pluginloader.h"
0028 #include "private/package_p.h"
0029 #include "private/packagestructure_p.h"
0030 
0031 namespace Plasma
0032 {
0033 PackagePrivate::PackagePrivate()
0034     : internalPackage(nullptr)
0035     , fallbackPackage(nullptr)
0036     , structure(nullptr)
0037 {
0038 }
0039 
0040 PackagePrivate::~PackagePrivate()
0041 {
0042 }
0043 
0044 Package::Package(PackageStructure *structure)
0045     : d(new Plasma::PackagePrivate())
0046 {
0047     d->structure = structure;
0048 
0049     if (!structure) {
0050         d->internalPackage = new KPackage::Package();
0051         return;
0052     }
0053 
0054     if (!structure->d->internalStructure) {
0055         d->structure->d->internalStructure = new KPackage::PackageStructure;
0056     }
0057 
0058     d->internalPackage = new KPackage::Package(structure->d->internalStructure);
0059     PackageStructureWrapper::s_packagesMap[d->internalPackage] = this;
0060     structure->initPackage(this);
0061 }
0062 
0063 Package::Package(const Package &other)
0064     : d(new Plasma::PackagePrivate())
0065 {
0066     d->internalPackage = new KPackage::Package(*other.d->internalPackage);
0067     d->structure = other.d->structure;
0068     PackageStructureWrapper::s_packagesMap[d->internalPackage] = this;
0069 }
0070 
0071 Package::Package(const KPackage::Package &other)
0072     : d(new Plasma::PackagePrivate())
0073 {
0074     d->internalPackage = new KPackage::Package(other);
0075     PackageStructureWrapper::s_packagesMap[d->internalPackage] = this;
0076 }
0077 
0078 Package::~Package()
0079 {
0080     PackageStructureWrapper::s_packagesMap.remove(d->internalPackage);
0081     delete d->internalPackage;
0082 }
0083 
0084 Package &Package::operator=(const Package &rhs)
0085 {
0086     if (&rhs != this) {
0087         d->internalPackage = new KPackage::Package(*rhs.d->internalPackage);
0088         d->structure = rhs.d->structure;
0089         PackageStructureWrapper::s_packagesMap[d->internalPackage] = this;
0090     }
0091 
0092     return *this;
0093 }
0094 
0095 bool Package::hasValidStructure() const
0096 {
0097     return d->internalPackage->hasValidStructure();
0098 }
0099 
0100 bool Package::isValid() const
0101 {
0102     return d->internalPackage->isValid();
0103 }
0104 
0105 QString Package::name(const char *key) const
0106 {
0107     return d->internalPackage->name(key);
0108 }
0109 
0110 bool Package::isRequired(const char *key) const
0111 {
0112     return d->internalPackage->isRequired(key);
0113 }
0114 
0115 QStringList Package::mimeTypes(const char *key) const
0116 {
0117     return d->internalPackage->mimeTypes(key);
0118 }
0119 
0120 QString Package::defaultPackageRoot() const
0121 {
0122     return d->internalPackage->defaultPackageRoot();
0123 }
0124 
0125 void Package::setDefaultPackageRoot(const QString &packageRoot)
0126 {
0127     d->internalPackage->setDefaultPackageRoot(packageRoot);
0128 }
0129 
0130 void Package::setFallbackPackage(const Plasma::Package &package)
0131 {
0132     d->fallbackPackage = new Package(package);
0133     d->internalPackage->setFallbackPackage(*package.d->internalPackage);
0134 }
0135 
0136 Plasma::Package Package::fallbackPackage() const
0137 {
0138     if (d->fallbackPackage) {
0139         return (*d->fallbackPackage);
0140     } else {
0141         return Package();
0142     }
0143 }
0144 
0145 QString Package::servicePrefix() const
0146 {
0147     return d->servicePrefix;
0148 }
0149 
0150 void Package::setServicePrefix(const QString &servicePrefix)
0151 {
0152     d->servicePrefix = servicePrefix;
0153 }
0154 
0155 KPackage::Package Package::kPackage() const
0156 {
0157     return *d->internalPackage;
0158 }
0159 
0160 bool Package::allowExternalPaths() const
0161 {
0162     return d->internalPackage->allowExternalPaths();
0163 }
0164 
0165 void Package::setAllowExternalPaths(bool allow)
0166 {
0167     d->internalPackage->setAllowExternalPaths(allow);
0168 }
0169 
0170 KPluginInfo Package::metadata() const
0171 {
0172     return KPluginInfo::fromMetaData(d->internalPackage->metadata());
0173 }
0174 
0175 QString Package::filePath(const char *fileType, const QString &filename) const
0176 {
0177     return d->internalPackage->filePath(fileType, filename);
0178 }
0179 
0180 QStringList Package::entryList(const char *key) const
0181 {
0182     return d->internalPackage->entryList(key);
0183 }
0184 
0185 void Package::setPath(const QString &path)
0186 {
0187     if (path == d->internalPackage->path()) {
0188         return;
0189     }
0190 
0191     d->internalPackage->setPath(path);
0192 }
0193 
0194 const QString Package::path() const
0195 {
0196     return d->internalPackage->path();
0197 }
0198 
0199 QStringList Package::contentsPrefixPaths() const
0200 {
0201     return d->internalPackage->contentsPrefixPaths();
0202 }
0203 
0204 void Package::setContentsPrefixPaths(const QStringList &prefixPaths)
0205 {
0206     d->internalPackage->setContentsPrefixPaths(prefixPaths);
0207 }
0208 
0209 QString Package::contentsHash() const
0210 {
0211     return QString::fromLocal8Bit(d->internalPackage->cryptographicHash(QCryptographicHash::Sha1));
0212 }
0213 
0214 void Package::addDirectoryDefinition(const char *key, const QString &path, const QString &name)
0215 {
0216     d->internalPackage->addDirectoryDefinition(key, path, name);
0217 }
0218 
0219 void Package::addFileDefinition(const char *key, const QString &path, const QString &name)
0220 {
0221     d->internalPackage->addFileDefinition(key, path, name);
0222 }
0223 
0224 void Package::removeDefinition(const char *key)
0225 {
0226     d->internalPackage->removeDefinition(key);
0227 }
0228 
0229 void Package::setRequired(const char *key, bool required)
0230 {
0231     d->internalPackage->setRequired(key, required);
0232 }
0233 
0234 void Package::setDefaultMimeTypes(QStringList mimeTypes)
0235 {
0236     d->internalPackage->setDefaultMimeTypes(mimeTypes);
0237 }
0238 
0239 void Package::setMimeTypes(const char *key, QStringList mimeTypes)
0240 {
0241     d->internalPackage->setMimeTypes(key, mimeTypes);
0242 }
0243 
0244 QList<const char *> Package::directories() const
0245 {
0246     QList<const char *> dirs;
0247     const auto directories = d->internalPackage->directories();
0248     for (const auto &data : directories) {
0249         dirs << data.constData();
0250     }
0251 
0252     return dirs;
0253 }
0254 
0255 QList<const char *> Package::requiredDirectories() const
0256 {
0257     QList<const char *> dirs;
0258     const auto directories = d->internalPackage->requiredDirectories();
0259     for (const auto &data : directories) {
0260         dirs << data.constData();
0261     }
0262 
0263     return dirs;
0264 }
0265 
0266 QList<const char *> Package::files() const
0267 {
0268     QList<const char *> files;
0269     const auto lstFiles = d->internalPackage->files();
0270     for (const auto &data : lstFiles) {
0271         files << data.constData();
0272     }
0273 
0274     return files;
0275 }
0276 
0277 QList<const char *> Package::requiredFiles() const
0278 {
0279     QList<const char *> files;
0280     const auto lstFiles = d->internalPackage->requiredFiles();
0281     for (const auto &data : lstFiles) {
0282         files << data.constData();
0283     }
0284 
0285     return files;
0286 }
0287 
0288 KJob *Package::install(const QString &sourcePackage, const QString &packageRoot)
0289 {
0290     const QString src = sourcePackage;
0291     const QString dest = packageRoot.isEmpty() ? defaultPackageRoot() : packageRoot;
0292     // qCDebug(LOG_PLASMA) << "Source: " << src;
0293     // qCDebug(LOG_PLASMA) << "PackageRoot: " << dest;
0294     KJob *j = d->structure->install(this, src, dest);
0295     return j;
0296 }
0297 
0298 KJob *Package::uninstall(const QString &packageName, const QString &packageRoot)
0299 {
0300     setPath(packageRoot + packageName);
0301 
0302     return d->structure->uninstall(this, packageRoot);
0303 }
0304 
0305 } // Namespace