Added cache extractor to the tools directory

It should find the local High Fidelity/Interface qt cache,
iterate over each file in the cache and output each corresponding
file into the High Fidelity/Interface/extracted dir.
The file path will be determined from the source url.

Untested on windows.
This commit is contained in:
Anthony J. Thibault 2015-11-06 14:52:12 -08:00
parent 1dc392bb36
commit c002888808
5 changed files with 198 additions and 0 deletions

View file

@ -10,3 +10,6 @@ set_target_properties(udt-test PROPERTIES FOLDER "Tools")
add_subdirectory(vhacd-util)
set_target_properties(vhacd-util PROPERTIES FOLDER "Tools")
add_subdirectory(cache-extract)
set_target_properties(cache-extract PROPERTIES FOLDER "Tools")

View file

@ -0,0 +1,6 @@
set(TARGET_NAME cache-extract)
setup_hifi_project()
link_hifi_libraries()

View file

@ -0,0 +1,125 @@
//
// CacheExtractApp.cpp
// tools/cache-extract/src
//
// Created by Anthony Thibault on 11/6/2015.
// Copyright 2015 High Fidelity, Inc.
//
// Distributed under the Apache License, Version 2.0.
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
//
#include "CacheExtractApp.h"
#include <QDebug>
#include <QStandardPaths>
#include <QDir>
#include <QtNetwork/QAbstractNetworkCache>
// extracted from qnetworkdiskcache.cpp
#define CACHE_VERSION 8
enum {
CacheMagic = 0xe8,
CurrentCacheVersion = CACHE_VERSION
};
#define DATA_DIR QLatin1String("data")
CacheExtractApp::CacheExtractApp(int& argc, char** argv) :
QCoreApplication(argc, argv)
{
QString myDataLoc = QStandardPaths::writableLocation(QStandardPaths::DataLocation);
int lastSlash = myDataLoc.lastIndexOf(QDir::separator());
QString cachePath = myDataLoc.leftRef(lastSlash).toString() + QDir::separator() +
"High Fidelity" + QDir::separator() + "Interface" + QDir::separator() +
DATA_DIR + QString::number(CACHE_VERSION) + QLatin1Char('/');
QString outputPath = myDataLoc.leftRef(lastSlash).toString() + QDir::separator() +
"High Fidelity" + QDir::separator() + "Interface" + QDir::separator() + "extracted";
qDebug() << "Searching cachePath = " << cachePath << "...";
// build list of files
QList<QString> fileList;
QDir dir(cachePath);
dir.setFilter(QDir::AllDirs | QDir::NoDotAndDotDot);
QFileInfoList list = dir.entryInfoList();
for (int i = 0; i < list.size(); ++i) {
QFileInfo fileInfo = list.at(i);
if (fileInfo.isDir()) {
QDir subDir(fileInfo.filePath());
subDir.setFilter(QDir::Files);
QFileInfoList subList = subDir.entryInfoList();
for (int j = 0; j < subList.size(); ++j) {
fileList << subList.at(j).filePath();
}
}
}
// dump each cache file into the outputPath
for (int i = 0; i < fileList.size(); ++i) {
QByteArray contents;
MyMetaData metaData;
if (extractFile(fileList.at(i), metaData, contents)) {
QString outFileName = outputPath + metaData.url.path();
int lastSlash = outFileName.lastIndexOf(QDir::separator());
QString outDirName = outFileName.leftRef(lastSlash).toString();
QDir dir(outputPath);
dir.mkpath(outDirName);
QFile out(outFileName);
if (out.open(QIODevice::WriteOnly)) {
out.write(contents);
out.close();
}
} else {
qCritical() << "Error extracting = " << fileList.at(i);
}
}
QMetaObject::invokeMethod(this, "quit", Qt::QueuedConnection);
}
bool CacheExtractApp::extractFile(const QString& filePath, MyMetaData& metaData, QByteArray& data) const {
QFile f(filePath);
if (!f.open(QIODevice::ReadOnly)) {
qDebug() << "error opening " << filePath;
return false;
}
QDataStream in(&f);
// from qnetworkdiskcache.cpp QCacheItem::read()
qint32 marker, version, streamVersion;
in >> marker;
if (marker != CacheMagic) {
return false;
}
in >> version;
if (version != CurrentCacheVersion) {
return false;
}
in >> streamVersion;
if (streamVersion > in.version())
return false;
in.setVersion(streamVersion);
bool compressed;
in >> metaData;
in >> compressed;
if (compressed) {
QByteArray compressedData;
in >> compressedData;
QBuffer buffer;
buffer.setData(qUncompress(compressedData));
buffer.open(QBuffer::ReadOnly);
data = buffer.readAll();
} else {
data = f.readAll();
}
return true;
}
QDataStream &operator>>(QDataStream& in, MyMetaData& metaData) {
in >> metaData.url;
in >> metaData.expirationDate;
in >> metaData.lastModified;
in >> metaData.saveToDisk;
in >> metaData.attributes;
in >> metaData.rawHeaders;
}

View file

@ -0,0 +1,47 @@
//
// CacheExtractApp.h
// tools/cache-extract/src
//
// Created by Anthony Thibault on 11/6/2015
// Copyright 2015 High Fidelity, Inc.
//
// Distributed under the Apache License, Version 2.0.
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
//
#ifndef hifi_CacheExtractApp_h
#define hifi_CacheExtractApp_h
#include <QtCore/QCoreApplication>
#include <QtCore/QCommandLineParser>
#include <QtNetwork/QNetworkDiskCache>
#include <QBuffer>
#include <QDateTime>
#include <QtNetwork/QNetworkRequest>
// copy of QNetworkCacheMetaData
class MyMetaData {
public:
typedef QPair<QByteArray, QByteArray> RawHeader;
typedef QList<RawHeader> RawHeaderList;
typedef QHash<qint32, QVariant> AttributesMap;
QUrl url;
QDateTime expirationDate;
QDateTime lastModified;
bool saveToDisk;
AttributesMap attributes;
RawHeaderList rawHeaders;
};
QDataStream &operator>>(QDataStream &, MyMetaData &);
class CacheExtractApp : public QCoreApplication {
Q_OBJECT
public:
CacheExtractApp(int& argc, char** argv);
bool extractFile(const QString& filePath, MyMetaData& metaData, QByteArray& data) const;
};
#endif // hifi_CacheExtractApp_h

View file

@ -0,0 +1,17 @@
//
// main.cpp
// tools/cache-extract/src
//
// Created by Anthony Thibault on 11/6/2015.
// Copyright 2015 High Fidelity, Inc.
//
// Distributed under the Apache License, Version 2.0.
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
#include <QtCore/QCoreApplication>
#include "CacheExtractApp.h"
int main (int argc, char** argv) {
CacheExtractApp app(argc, argv);
return app.exec();
}