mirror of
https://github.com/HifiExperiments/overte.git
synced 2025-08-09 17:38:34 +02:00
Merge pull request #586 from makitsune/relative-urls
Allow resolving relative urls when importing entities json
This commit is contained in:
commit
6a872ef525
4 changed files with 93 additions and 12 deletions
|
@ -685,8 +685,9 @@ bool Octree::readFromFile(const char* fileName) {
|
||||||
QDataStream fileInputStream(&file);
|
QDataStream fileInputStream(&file);
|
||||||
QFileInfo fileInfo(qFileName);
|
QFileInfo fileInfo(qFileName);
|
||||||
uint64_t fileLength = fileInfo.size();
|
uint64_t fileLength = fileInfo.size();
|
||||||
|
QUrl relativeURL = QUrl::fromLocalFile(qFileName).adjusted(QUrl::RemoveFilename);
|
||||||
|
|
||||||
bool success = readFromStream(fileLength, fileInputStream);
|
bool success = readFromStream(fileLength, fileInputStream, "", false, relativeURL);
|
||||||
|
|
||||||
file.close();
|
file.close();
|
||||||
|
|
||||||
|
@ -708,7 +709,9 @@ bool Octree::readJSONFromGzippedFile(QString qFileName) {
|
||||||
}
|
}
|
||||||
|
|
||||||
QDataStream jsonStream(jsonData);
|
QDataStream jsonStream(jsonData);
|
||||||
return readJSONFromStream(-1, jsonStream);
|
QUrl relativeURL = QUrl::fromLocalFile(qFileName).adjusted(QUrl::RemoveFilename);
|
||||||
|
|
||||||
|
return readJSONFromStream(-1, jsonStream, "", false, relativeURL);
|
||||||
}
|
}
|
||||||
|
|
||||||
// hack to get the marketplace id into the entities. We will create a way to get this from a hash of
|
// hack to get the marketplace id into the entities. We will create a way to get this from a hash of
|
||||||
|
@ -761,13 +764,15 @@ bool Octree::readFromURL(
|
||||||
QByteArray uncompressedJsonData;
|
QByteArray uncompressedJsonData;
|
||||||
bool wasCompressed = gunzip(data, uncompressedJsonData);
|
bool wasCompressed = gunzip(data, uncompressedJsonData);
|
||||||
|
|
||||||
|
QUrl relativeURL = QUrl(urlString).adjusted(QUrl::RemoveFilename);
|
||||||
|
|
||||||
if (wasCompressed) {
|
if (wasCompressed) {
|
||||||
QDataStream inputStream(uncompressedJsonData);
|
QDataStream inputStream(uncompressedJsonData);
|
||||||
return readFromStream(uncompressedJsonData.size(), inputStream, marketplaceID);
|
return readFromStream(uncompressedJsonData.size(), inputStream, marketplaceID, isImport, relativeURL);
|
||||||
}
|
}
|
||||||
|
|
||||||
QDataStream inputStream(data);
|
QDataStream inputStream(data);
|
||||||
return readFromStream(data.size(), inputStream, marketplaceID, isImport);
|
return readFromStream(data.size(), inputStream, marketplaceID, isImport, relativeURL);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Octree::readFromByteArray(
|
bool Octree::readFromByteArray(
|
||||||
|
@ -780,20 +785,23 @@ bool Octree::readFromByteArray(
|
||||||
QByteArray uncompressedJsonData;
|
QByteArray uncompressedJsonData;
|
||||||
bool wasCompressed = gunzip(data, uncompressedJsonData);
|
bool wasCompressed = gunzip(data, uncompressedJsonData);
|
||||||
|
|
||||||
|
QUrl relativeURL = QUrl(urlString).adjusted(QUrl::RemoveFilename);
|
||||||
|
|
||||||
if (wasCompressed) {
|
if (wasCompressed) {
|
||||||
QDataStream inputStream(uncompressedJsonData);
|
QDataStream inputStream(uncompressedJsonData);
|
||||||
return readFromStream(uncompressedJsonData.size(), inputStream, marketplaceID);
|
return readFromStream(uncompressedJsonData.size(), inputStream, marketplaceID, false, relativeURL);
|
||||||
}
|
}
|
||||||
|
|
||||||
QDataStream inputStream(data);
|
QDataStream inputStream(data);
|
||||||
return readFromStream(data.size(), inputStream, marketplaceID);
|
return readFromStream(data.size(), inputStream, marketplaceID, false, relativeURL);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Octree::readFromStream(
|
bool Octree::readFromStream(
|
||||||
uint64_t streamLength,
|
uint64_t streamLength,
|
||||||
QDataStream& inputStream,
|
QDataStream& inputStream,
|
||||||
const QString& marketplaceID,
|
const QString& marketplaceID,
|
||||||
const bool isImport
|
const bool isImport,
|
||||||
|
const QUrl& relativeURL
|
||||||
) {
|
) {
|
||||||
// decide if this is binary SVO or JSON-formatted SVO
|
// decide if this is binary SVO or JSON-formatted SVO
|
||||||
QIODevice *device = inputStream.device();
|
QIODevice *device = inputStream.device();
|
||||||
|
@ -806,7 +814,7 @@ bool Octree::readFromStream(
|
||||||
return false;
|
return false;
|
||||||
} else {
|
} else {
|
||||||
qCDebug(octree) << "Reading from JSON SVO Stream length:" << streamLength;
|
qCDebug(octree) << "Reading from JSON SVO Stream length:" << streamLength;
|
||||||
return readJSONFromStream(streamLength, inputStream, marketplaceID, isImport);
|
return readJSONFromStream(streamLength, inputStream, marketplaceID, isImport, relativeURL);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -837,7 +845,8 @@ bool Octree::readJSONFromStream(
|
||||||
uint64_t streamLength,
|
uint64_t streamLength,
|
||||||
QDataStream& inputStream,
|
QDataStream& inputStream,
|
||||||
const QString& marketplaceID, /*=""*/
|
const QString& marketplaceID, /*=""*/
|
||||||
const bool isImport
|
const bool isImport,
|
||||||
|
const QUrl& relativeURL
|
||||||
) {
|
) {
|
||||||
// if the data is gzipped we may not have a useful bytesAvailable() result, so just keep reading until
|
// if the data is gzipped we may not have a useful bytesAvailable() result, so just keep reading until
|
||||||
// we get an eof. Leave streamLength parameter for consistency.
|
// we get an eof. Leave streamLength parameter for consistency.
|
||||||
|
@ -858,7 +867,9 @@ bool Octree::readJSONFromStream(
|
||||||
}
|
}
|
||||||
|
|
||||||
OctreeEntitiesFileParser octreeParser;
|
OctreeEntitiesFileParser octreeParser;
|
||||||
|
octreeParser.relativeURL = relativeURL;
|
||||||
octreeParser.setEntitiesString(jsonBuffer);
|
octreeParser.setEntitiesString(jsonBuffer);
|
||||||
|
|
||||||
QVariantMap asMap;
|
QVariantMap asMap;
|
||||||
if (!octreeParser.parseEntities(asMap)) {
|
if (!octreeParser.parseEntities(asMap)) {
|
||||||
qCritical() << "Couldn't parse Entities JSON:" << octreeParser.getErrorString().c_str();
|
qCritical() << "Couldn't parse Entities JSON:" << octreeParser.getErrorString().c_str();
|
||||||
|
|
|
@ -218,8 +218,8 @@ public:
|
||||||
bool readFromFile(const char* filename);
|
bool readFromFile(const char* filename);
|
||||||
bool readFromURL(const QString& url, const bool isObservable = true, const qint64 callerId = -1, const bool isImport = false); // will support file urls as well...
|
bool readFromURL(const QString& url, const bool isObservable = true, const qint64 callerId = -1, const bool isImport = false); // will support file urls as well...
|
||||||
bool readFromByteArray(const QString& url, const QByteArray& byteArray);
|
bool readFromByteArray(const QString& url, const QByteArray& byteArray);
|
||||||
bool readFromStream(uint64_t streamLength, QDataStream& inputStream, const QString& marketplaceID="", const bool isImport = false);
|
bool readFromStream(uint64_t streamLength, QDataStream& inputStream, const QString& marketplaceID="", const bool isImport = false, const QUrl& urlString = QUrl());
|
||||||
bool readJSONFromStream(uint64_t streamLength, QDataStream& inputStream, const QString& marketplaceID="", const bool isImport = false);
|
bool readJSONFromStream(uint64_t streamLength, QDataStream& inputStream, const QString& marketplaceID="", const bool isImport = false, const QUrl& urlString = QUrl());
|
||||||
bool readJSONFromGzippedFile(QString qFileName);
|
bool readJSONFromGzippedFile(QString qFileName);
|
||||||
virtual bool readFromMap(QVariantMap& entityDescription, const bool isImport = false) = 0;
|
virtual bool readFromMap(QVariantMap& entityDescription, const bool isImport = false) = 0;
|
||||||
|
|
||||||
|
|
|
@ -237,7 +237,75 @@ bool OctreeEntitiesFileParser::readEntitiesArray(QVariantList& entitiesArray) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
entitiesArray.append(entity.object());
|
QJsonObject entityObject = entity.object();
|
||||||
|
|
||||||
|
// resolve urls starting with ./ or ../
|
||||||
|
if (relativeURL.isEmpty() == false) {
|
||||||
|
bool isDirty = false;
|
||||||
|
|
||||||
|
const QStringList urlKeys {
|
||||||
|
// model
|
||||||
|
"modelURL",
|
||||||
|
"animation.url",
|
||||||
|
// image
|
||||||
|
"imageURL",
|
||||||
|
// web
|
||||||
|
"sourceUrl",
|
||||||
|
"scriptURL",
|
||||||
|
// zone
|
||||||
|
"ambientLight.ambientURL",
|
||||||
|
"skybox.url",
|
||||||
|
// particles
|
||||||
|
"textures",
|
||||||
|
// materials
|
||||||
|
"materialURL",
|
||||||
|
// ...shared
|
||||||
|
"href",
|
||||||
|
"script",
|
||||||
|
"serverScripts",
|
||||||
|
"collisionSoundURL",
|
||||||
|
"compoundShapeURL",
|
||||||
|
// TODO: deal with materialData and userData
|
||||||
|
};
|
||||||
|
|
||||||
|
for (const QString& key : urlKeys) {
|
||||||
|
if (key.contains('.')) {
|
||||||
|
// url is inside another object
|
||||||
|
const QStringList keyPair = key.split('.');
|
||||||
|
const QString entityKey = keyPair[0];
|
||||||
|
const QString childKey = keyPair[1];
|
||||||
|
|
||||||
|
if (entityObject.contains(entityKey) && entityObject[entityKey].isObject()) {
|
||||||
|
QJsonObject childObject = entityObject[entityKey].toObject();
|
||||||
|
|
||||||
|
if (childObject.contains(childKey) && childObject[childKey].isString()) {
|
||||||
|
const QString url = childObject[childKey].toString();
|
||||||
|
|
||||||
|
if (url.startsWith("./") || url.startsWith("../")) {
|
||||||
|
childObject[childKey] = relativeURL.resolved(url).toString();
|
||||||
|
entityObject[entityKey] = childObject;
|
||||||
|
isDirty = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (entityObject.contains(key) && entityObject[key].isString()) {
|
||||||
|
const QString url = entityObject[key].toString();
|
||||||
|
|
||||||
|
if (url.startsWith("./") || url.startsWith("../")) {
|
||||||
|
entityObject[key] = relativeURL.resolved(url).toString();
|
||||||
|
isDirty = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isDirty) {
|
||||||
|
entity.setObject(entityObject);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
entitiesArray.append(entityObject);
|
||||||
_position = matchingBrace;
|
_position = matchingBrace;
|
||||||
char c = nextToken();
|
char c = nextToken();
|
||||||
if (c == ']') {
|
if (c == ']') {
|
||||||
|
|
|
@ -16,12 +16,14 @@
|
||||||
|
|
||||||
#include <QByteArray>
|
#include <QByteArray>
|
||||||
#include <QVariant>
|
#include <QVariant>
|
||||||
|
#include <QUrl>
|
||||||
|
|
||||||
class OctreeEntitiesFileParser {
|
class OctreeEntitiesFileParser {
|
||||||
public:
|
public:
|
||||||
void setEntitiesString(const QByteArray& entitiesContents);
|
void setEntitiesString(const QByteArray& entitiesContents);
|
||||||
bool parseEntities(QVariantMap& parsedEntities);
|
bool parseEntities(QVariantMap& parsedEntities);
|
||||||
std::string getErrorString() const;
|
std::string getErrorString() const;
|
||||||
|
QUrl relativeURL;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
int nextToken();
|
int nextToken();
|
||||||
|
|
Loading…
Reference in a new issue