Make validation of zipped packages possible

- move the unpack block into its own function
- unzip if necessary, and point validator and metadata loader at this
  function
- manually delete the tempdir, to keep it as long as the Package is
  alive

This patch makes it possible to upgrade packages from .plasmoid files.
This commit is contained in:
Sebastian Kügler 2013-02-27 06:46:28 +01:00
parent 722640d8e8
commit 90b022435a
2 changed files with 49 additions and 26 deletions

View File

@ -85,6 +85,10 @@ bool Package::isValid() const
//even if it's a big nested loop, usually there is one prefix and one location //even if it's a big nested loop, usually there is one prefix and one location
//so shouldn't cause too much disk access //so shouldn't cause too much disk access
QHashIterator<QByteArray, ContentStructure> it(d->contents); QHashIterator<QByteArray, ContentStructure> it(d->contents);
QString p = d->path;
if (!d->tempRoot.isEmpty()) {
p = d->tempRoot;
}
while (it.hasNext()) { while (it.hasNext()) {
it.next(); it.next();
if (!it.value().required) { if (!it.value().required) {
@ -94,7 +98,7 @@ bool Package::isValid() const
bool failed = true; bool failed = true;
foreach (const QString &path, it.value().paths) { foreach (const QString &path, it.value().paths) {
foreach (const QString &prefix, d->contentsPrefixPaths) { foreach (const QString &prefix, d->contentsPrefixPaths) {
if (QFile::exists(d->path + prefix + path)) { if (QFile::exists(p + prefix + path)) {
failed = false; failed = false;
break; break;
} }
@ -213,30 +217,7 @@ KPluginInfo Package::metadata() const
d->createPackageMetadata(d->path); d->createPackageMetadata(d->path);
} else if (fileInfo.exists()) { } else if (fileInfo.exists()) {
d->path = p; d->path = p;
KArchive *archive = 0; d->tempRoot = d->unpack(p);
QMimeDatabase db;
QMimeType mimeType = db.mimeTypeForFile(p);
if (mimeType.inherits("application/zip")) {
archive = new KZip(d->path);
} else if (mimeType.inherits("application/x-compressed-tar") || mimeType.inherits("application/x-gzip") ||
mimeType.inherits("application/x-tar") || mimeType.inherits("application/x-bzip-compressed-tar") ||
mimeType.inherits("application/x-xz") || mimeType.inherits("application/x-lzma")) {
archive = new KTar(d->path);
} else {
kWarning() << "Could not open package file, unsupported archive format:" << d->path << mimeType.name();
}
if (archive && archive->open(QIODevice::ReadOnly)) {
const KArchiveDirectory *source = archive->directory();
QTemporaryDir tempdir;
source->copyTo(tempdir.path() + '/');
d->createPackageMetadata(tempdir.path() + '/');
} else {
kWarning() << "Could not open package file:" << d->path;
}
delete archive;
} }
} }
} }
@ -248,6 +229,36 @@ KPluginInfo Package::metadata() const
return *d->metadata; return *d->metadata;
} }
QString PackagePrivate::unpack(const QString& filePath) {
KArchive *archive = 0;
QMimeDatabase db;
QMimeType mimeType = db.mimeTypeForFile(filePath);
if (mimeType.inherits("application/zip")) {
archive = new KZip(filePath);
} else if (mimeType.inherits("application/x-compressed-tar") || mimeType.inherits("application/x-gzip") ||
mimeType.inherits("application/x-tar") || mimeType.inherits("application/x-bzip-compressed-tar") ||
mimeType.inherits("application/x-xz") || mimeType.inherits("application/x-lzma")) {
archive = new KTar(filePath);
} else {
kWarning() << "Could not open package file, unsupported archive format:" << filePath << mimeType.name();
}
QString tempRoot;
if (archive && archive->open(QIODevice::ReadOnly)) {
const KArchiveDirectory *source = archive->directory();
QTemporaryDir tempdir;
tempdir.setAutoRemove(false);
source->copyTo(tempdir.path() + '/');
createPackageMetadata(tempdir.path() + '/');
tempRoot = tempdir.path() + '/';
} else {
kWarning() << "Could not open package file:" << path;
}
delete archive;
return tempRoot;
}
QString Package::filePath(const char *fileType, const QString &filename) const QString Package::filePath(const char *fileType, const QString &filename) const
{ {
if (!d->valid) { if (!d->valid) {
@ -418,7 +429,6 @@ void Package::setPath(const QString &path)
} else { } else {
p = d->defaultPackageRoot % path % "/"; p = d->defaultPackageRoot % path % "/";
} }
if (QDir::isRelativePath(p)) { if (QDir::isRelativePath(p)) {
paths << QStandardPaths::locateAll(QStandardPaths::GenericDataLocation, p, QStandardPaths::LocateDirectory); paths << QStandardPaths::locateAll(QStandardPaths::GenericDataLocation, p, QStandardPaths::LocateDirectory);
} else { } else {
@ -433,6 +443,13 @@ void Package::setPath(const QString &path)
paths << path; paths << path;
} }
} }
QFileInfo fileInfo(path);
if (fileInfo.isFile() && d->tempRoot.isEmpty()) {
qDebug() << "before unzip: path " << path;
d->path = path;
d->tempRoot = d->unpack(path);
}
// now we search each path found, caching our previous path to know if // now we search each path found, caching our previous path to know if
// anything actually really changed // anything actually really changed
@ -714,6 +731,10 @@ PackagePrivate::PackagePrivate(const PackagePrivate &other)
PackagePrivate::~PackagePrivate() PackagePrivate::~PackagePrivate()
{ {
if (!tempRoot.isEmpty()) {
QDir dir(tempRoot);
dir.removeRecursively();
}
delete metadata; delete metadata;
} }

View File

@ -71,10 +71,12 @@ public:
PackagePrivate &operator=(const PackagePrivate &rhs); PackagePrivate &operator=(const PackagePrivate &rhs);
void createPackageMetadata(const QString &path); void createPackageMetadata(const QString &path);
QString unpack(const QString &filePath);
void updateHash(const QString &basePath, const QString &subPath, const QDir &dir, QCryptographicHash &hash); void updateHash(const QString &basePath, const QString &subPath, const QDir &dir, QCryptographicHash &hash);
QWeakPointer<PackageStructure> structure; QWeakPointer<PackageStructure> structure;
QString path; QString path;
QString tempRoot;
QStringList contentsPrefixPaths; QStringList contentsPrefixPaths;
QString defaultPackageRoot; QString defaultPackageRoot;
QString servicePrefix; QString servicePrefix;