FEATURE: fallback paths for the contents prefixes as well.
this is basically a merge of http://reviewboard.kde.org/r/5765/ with http://svn.reviewboard.kde.org/r/5763 svn path=/trunk/KDE/kdelibs/; revision=1193135
This commit is contained in:
parent
c09422cc8c
commit
5e9d88496a
80
package.cpp
80
package.cpp
@ -158,15 +158,23 @@ Package &Package::operator=(const Package &rhs)
|
|||||||
|
|
||||||
bool Package::isValid() const
|
bool Package::isValid() const
|
||||||
{
|
{
|
||||||
if (!d->valid) {
|
if (!d->valid || d->structure->contentsPrefixPaths().isEmpty()) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//search for the file in all prefixes and in all possible paths for each prefix
|
||||||
|
//even if it's a big nested loop, usually there is one prefix and one location
|
||||||
|
//so shouldn't cause too much disk access
|
||||||
foreach (const char *dir, d->structure->requiredDirectories()) {
|
foreach (const char *dir, d->structure->requiredDirectories()) {
|
||||||
bool failed = true;
|
bool failed = true;
|
||||||
foreach (const QString &path, d->structure->searchPath(dir)) {
|
foreach (const QString &path, d->structure->searchPath(dir)) {
|
||||||
if (QFile::exists(d->structure->path() + d->structure->contentsPrefix() + path)) {
|
foreach (const QString &prefix, d->structure->contentsPrefixPaths()) {
|
||||||
failed = false;
|
if (QFile::exists(d->structure->path() + prefix + path)) {
|
||||||
|
failed = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!failed) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -181,8 +189,13 @@ bool Package::isValid() const
|
|||||||
foreach (const char *file, d->structure->requiredFiles()) {
|
foreach (const char *file, d->structure->requiredFiles()) {
|
||||||
bool failed = true;
|
bool failed = true;
|
||||||
foreach (const QString &path, d->structure->searchPath(file)) {
|
foreach (const QString &path, d->structure->searchPath(file)) {
|
||||||
if (QFile::exists(d->structure->path() + d->structure->contentsPrefix() + path)) {
|
foreach (const QString &prefix, d->structure->contentsPrefixPaths()) {
|
||||||
failed = false;
|
if (QFile::exists(d->structure->path() + prefix + path)) {
|
||||||
|
failed = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!failed) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -213,28 +226,35 @@ QString Package::filePath(const char *fileType, const QString &filename) const
|
|||||||
//kDebug() << "no matching path came of it, while looking for" << fileType << filename;
|
//kDebug() << "no matching path came of it, while looking for" << fileType << filename;
|
||||||
return QString();
|
return QString();
|
||||||
}
|
}
|
||||||
|
//when filetype is empty paths is always empty, so try with an empty string
|
||||||
|
} else {
|
||||||
|
paths << QString();
|
||||||
}
|
}
|
||||||
|
|
||||||
const QString prefix(d->structure->path() + d->structure->contentsPrefix());
|
//Nested loop, but in the medium case resolves to just one iteration
|
||||||
|
foreach (const QString &contentsPrefix, d->structure->contentsPrefixPaths()) {
|
||||||
|
const QString prefix(d->structure->path() + contentsPrefix);
|
||||||
|
|
||||||
foreach (const QString &path, paths) {
|
foreach (const QString &path, paths) {
|
||||||
QString file = prefix + path;
|
QString file = prefix + path;
|
||||||
|
|
||||||
if (!filename.isEmpty()) {
|
if (!filename.isEmpty()) {
|
||||||
file.append("/").append(filename);
|
file.append("/").append(filename);
|
||||||
}
|
|
||||||
|
|
||||||
if (QFile::exists(file)) {
|
|
||||||
if (d->structure->allowExternalPaths()) {
|
|
||||||
return file;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// ensure that we don't return files outside of our base path
|
if (QFile::exists(file)) {
|
||||||
// due to symlink or ../ games
|
if (d->structure->allowExternalPaths()) {
|
||||||
QDir dir(file);
|
return file;
|
||||||
QString canonicalized = dir.canonicalPath() + QDir::separator();
|
}
|
||||||
if (canonicalized.startsWith(d->structure->path())) {
|
|
||||||
return file;
|
// ensure that we don't return files outside of our base path
|
||||||
|
// due to symlink or ../ games
|
||||||
|
QDir dir(file);
|
||||||
|
QString canonicalized = dir.canonicalPath() + QDir::separator();
|
||||||
|
|
||||||
|
if (canonicalized.startsWith(d->structure->path())) {
|
||||||
|
return file;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -351,13 +371,6 @@ QString Package::contentsHash() const
|
|||||||
return QString();
|
return QString();
|
||||||
}
|
}
|
||||||
|
|
||||||
const QString basePath = d->structure->path() + d->structure->contentsPrefix();
|
|
||||||
QDir dir(basePath);
|
|
||||||
|
|
||||||
if (!dir.exists()) {
|
|
||||||
return QString();
|
|
||||||
}
|
|
||||||
|
|
||||||
QCA::Hash hash("sha1");
|
QCA::Hash hash("sha1");
|
||||||
QString metadataPath = d->structure->path() + "metadata.desktop";
|
QString metadataPath = d->structure->path() + "metadata.desktop";
|
||||||
if (QFile::exists(metadataPath)) {
|
if (QFile::exists(metadataPath)) {
|
||||||
@ -373,7 +386,16 @@ QString Package::contentsHash() const
|
|||||||
kWarning() << "no metadata at" << metadataPath;
|
kWarning() << "no metadata at" << metadataPath;
|
||||||
}
|
}
|
||||||
|
|
||||||
d->updateHash(basePath, QString(), dir, hash);
|
foreach (QString prefix, d->structure->contentsPrefixPaths()) {
|
||||||
|
const QString basePath = d->structure->path() + prefix;
|
||||||
|
QDir dir(basePath);
|
||||||
|
|
||||||
|
if (!dir.exists()) {
|
||||||
|
return QString();
|
||||||
|
}
|
||||||
|
|
||||||
|
d->updateHash(basePath, QString(), dir, hash);
|
||||||
|
}
|
||||||
return QCA::arrayToHex(hash.final().toByteArray());
|
return QCA::arrayToHex(hash.final().toByteArray());
|
||||||
#else
|
#else
|
||||||
// no QCA2!
|
// no QCA2!
|
||||||
|
@ -75,12 +75,12 @@ class PackageStructurePrivate
|
|||||||
public:
|
public:
|
||||||
PackageStructurePrivate(const QString &t)
|
PackageStructurePrivate(const QString &t)
|
||||||
: type(t),
|
: type(t),
|
||||||
contentsPrefix("contents/"),
|
|
||||||
packageRoot("plasma/plasmoids"),
|
packageRoot("plasma/plasmoids"),
|
||||||
servicePrefix("plasma-applet-"),
|
servicePrefix("plasma-applet-"),
|
||||||
metadata(0),
|
metadata(0),
|
||||||
externalPaths(false)
|
externalPaths(false)
|
||||||
{
|
{
|
||||||
|
contentsPrefixPaths << "contents/";
|
||||||
}
|
}
|
||||||
|
|
||||||
~PackageStructurePrivate()
|
~PackageStructurePrivate()
|
||||||
@ -94,7 +94,7 @@ public:
|
|||||||
|
|
||||||
QString type;
|
QString type;
|
||||||
QString path;
|
QString path;
|
||||||
QString contentsPrefix;
|
QStringList contentsPrefixPaths;
|
||||||
QString packageRoot;
|
QString packageRoot;
|
||||||
QString servicePrefix;
|
QString servicePrefix;
|
||||||
QMap<QByteArray, ContentStructure> contents;
|
QMap<QByteArray, ContentStructure> contents;
|
||||||
@ -282,22 +282,25 @@ QStringList PackageStructure::entryList(const char *key)
|
|||||||
return QStringList();
|
return QStringList();
|
||||||
}
|
}
|
||||||
|
|
||||||
QDir dir(d->path + d->contentsPrefix + p);
|
QStringList list;
|
||||||
|
foreach (QString prefix, d->contentsPrefixPaths) {
|
||||||
|
QDir dir(d->path + prefix + p);
|
||||||
|
|
||||||
if (dir.exists()) {
|
if (dir.exists()) {
|
||||||
if (d->externalPaths) {
|
if (d->externalPaths) {
|
||||||
return dir.entryList(QDir::Files | QDir::Readable);
|
return dir.entryList(QDir::Files | QDir::Readable);
|
||||||
}
|
}
|
||||||
|
|
||||||
// ensure that we don't return files outside of our base path
|
// ensure that we don't return files outside of our base path
|
||||||
// due to symlink or ../ games
|
// due to symlink or ../ games
|
||||||
QString canonicalized = dir.canonicalPath();
|
QString canonicalized = dir.canonicalPath();
|
||||||
if (canonicalized.startsWith(d->path)) {
|
if (canonicalized.startsWith(d->path)) {
|
||||||
return dir.entryList(QDir::Files | QDir::Readable);
|
list << dir.entryList(QDir::Files | QDir::Readable);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return QStringList();
|
return list;
|
||||||
}
|
}
|
||||||
|
|
||||||
void PackageStructure::addDirectoryDefinition(const char *key,
|
void PackageStructure::addDirectoryDefinition(const char *key,
|
||||||
@ -469,7 +472,7 @@ void PackageStructure::read(const KConfigBase *config)
|
|||||||
d->mimetypes.clear();
|
d->mimetypes.clear();
|
||||||
KConfigGroup general(config, QString());
|
KConfigGroup general(config, QString());
|
||||||
d->type = general.readEntry("Type", QString());
|
d->type = general.readEntry("Type", QString());
|
||||||
d->contentsPrefix = general.readEntry("ContentsPrefix", d->contentsPrefix);
|
d->contentsPrefixPaths = general.readEntry("ContentsPrefixPaths", d->contentsPrefixPaths);
|
||||||
d->packageRoot = general.readEntry("DefaultPackageRoot", d->packageRoot);
|
d->packageRoot = general.readEntry("DefaultPackageRoot", d->packageRoot);
|
||||||
d->externalPaths = general.readEntry("AllowExternalPaths", d->externalPaths);
|
d->externalPaths = general.readEntry("AllowExternalPaths", d->externalPaths);
|
||||||
|
|
||||||
@ -499,7 +502,7 @@ void PackageStructure::write(KConfigBase *config) const
|
|||||||
{
|
{
|
||||||
KConfigGroup general = KConfigGroup(config, "");
|
KConfigGroup general = KConfigGroup(config, "");
|
||||||
general.writeEntry("Type", type());
|
general.writeEntry("Type", type());
|
||||||
general.writeEntry("ContentsPrefix", d->contentsPrefix);
|
general.writeEntry("ContentsPrefixPaths", d->contentsPrefixPaths);
|
||||||
general.writeEntry("DefaultPackageRoot", d->packageRoot);
|
general.writeEntry("DefaultPackageRoot", d->packageRoot);
|
||||||
general.writeEntry("AllowExternalPaths", d->externalPaths);
|
general.writeEntry("AllowExternalPaths", d->externalPaths);
|
||||||
|
|
||||||
@ -524,12 +527,23 @@ void PackageStructure::write(KConfigBase *config) const
|
|||||||
|
|
||||||
QString PackageStructure::contentsPrefix() const
|
QString PackageStructure::contentsPrefix() const
|
||||||
{
|
{
|
||||||
return d->contentsPrefix;
|
return d->contentsPrefixPaths.first();
|
||||||
}
|
}
|
||||||
|
|
||||||
void PackageStructure::setContentsPrefix(const QString &prefix)
|
void PackageStructure::setContentsPrefix(const QString &prefix)
|
||||||
{
|
{
|
||||||
d->contentsPrefix = prefix;
|
d->contentsPrefixPaths.clear();
|
||||||
|
d->contentsPrefixPaths << prefix;
|
||||||
|
}
|
||||||
|
|
||||||
|
QStringList PackageStructure::contentsPrefixPaths() const
|
||||||
|
{
|
||||||
|
return d->contentsPrefixPaths;
|
||||||
|
}
|
||||||
|
|
||||||
|
void PackageStructure::setContentsPrefixPaths(const QStringList &prefixPaths)
|
||||||
|
{
|
||||||
|
d->contentsPrefixPaths = prefixPaths;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool PackageStructure::installPackage(const QString &package, const QString &packageRoot)
|
bool PackageStructure::installPackage(const QString &package, const QString &packageRoot)
|
||||||
|
@ -169,7 +169,9 @@ public:
|
|||||||
QString path(const char *key) const;
|
QString path(const char *key) const;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return a list of paths relative to the package root for the given entry
|
* @return a list of paths relative to the package root for the given entry.
|
||||||
|
* They are orted by importance: when searching for a file the paths
|
||||||
|
* will be searched in order
|
||||||
* @since 4.6
|
* @since 4.6
|
||||||
**/
|
**/
|
||||||
QStringList searchPath(const char *key) const;
|
QStringList searchPath(const char *key) const;
|
||||||
@ -284,8 +286,16 @@ public:
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @return the prefix inserted between the base path and content entries
|
* @return the prefix inserted between the base path and content entries
|
||||||
|
* @deprecated use contentsPrefixPaths() instead.
|
||||||
*/
|
*/
|
||||||
QString contentsPrefix() const;
|
KDE_DEPRECATED QString contentsPrefix() const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the prefix paths inserted between the base path and content entries, in order of priority.
|
||||||
|
* When searching for a file, all paths will be tried in order.
|
||||||
|
* @since 4.6
|
||||||
|
*/
|
||||||
|
QStringList contentsPrefixPaths() const;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return preferred package root. This defaults to plasma/plasmoids/
|
* @return preferred package root. This defaults to plasma/plasmoids/
|
||||||
@ -334,8 +344,22 @@ protected:
|
|||||||
* structure
|
* structure
|
||||||
*
|
*
|
||||||
* @arg prefix the directory prefix to use
|
* @arg prefix the directory prefix to use
|
||||||
|
* @deprecated use setContentsPrefixPaths() instead.
|
||||||
*/
|
*/
|
||||||
void setContentsPrefix(const QString &prefix);
|
KDE_DEPRECATED void setContentsPrefix(const QString &prefix);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the prefixes that all the contents in this package should
|
||||||
|
* appear under. This defaults to "contents/" and is added automatically
|
||||||
|
* between the base path and the entries as defined by the package
|
||||||
|
* structure. Multiple entries can be added.
|
||||||
|
* In this case each file request will be searched in all prefixes in order,
|
||||||
|
* and the first found will be returned.
|
||||||
|
*
|
||||||
|
* @arg prefix paths the directory prefix to use
|
||||||
|
* @since 4.6
|
||||||
|
*/
|
||||||
|
void setContentsPrefixPaths(const QStringList &prefixPaths);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets preferred package root.
|
* Sets preferred package root.
|
||||||
|
Loading…
x
Reference in New Issue
Block a user