From 52df77b4b560005aece460c907058fc055ac054b Mon Sep 17 00:00:00 2001 From: Atlante45 Date: Wed, 2 Apr 2014 16:25:35 -0700 Subject: [PATCH 1/3] Final work on models metadata support --- interface/src/ui/ModelsBrowser.cpp | 114 +++++++++++++++++------- interface/src/ui/ModelsBrowser.h | 14 ++- libraries/shared/src/FileDownloader.cpp | 45 ---------- libraries/shared/src/FileDownloader.h | 41 --------- 4 files changed, 87 insertions(+), 127 deletions(-) delete mode 100644 libraries/shared/src/FileDownloader.cpp delete mode 100644 libraries/shared/src/FileDownloader.h diff --git a/interface/src/ui/ModelsBrowser.cpp b/interface/src/ui/ModelsBrowser.cpp index 15f1e9111e..e128d047ef 100644 --- a/interface/src/ui/ModelsBrowser.cpp +++ b/interface/src/ui/ModelsBrowser.cpp @@ -8,11 +8,10 @@ #include #include -#include #include #include #include -#include +#include #include #include @@ -33,27 +32,39 @@ static const QString KEY_NAME = "Key"; static const QString LOADING_MSG = "Loading..."; static const QString ERROR_MSG = "Error loading files"; +static const QString DO_NOT_MODIFY_TAG = "DoNotModify"; + enum ModelMetaData { NAME, - CREATOR, - UPLOAD_DATE, TYPE, GENDER, + CREATOR, + UPLOAD_DATE, MODEL_METADATA_COUNT }; static const QString propertiesNames[MODEL_METADATA_COUNT] = { "Name", - "Creator", - "Upload Date", "Type", - "Gender" + "Gender", + "Creator", + "Last Modified" +}; +static const QString propertiesIds[MODEL_METADATA_COUNT] = { + DO_NOT_MODIFY_TAG, + "Type", + "Gender", + "x-amz-request-id", + "Last-Modified" }; ModelsBrowser::ModelsBrowser(ModelType modelsType, QWidget* parent) : QWidget(parent), _handler(new ModelHandler(modelsType)) { + connect(_handler, SIGNAL(doneDownloading()), SLOT(resizeView())); + connect(_handler, SIGNAL(updated()), SLOT(resizeView())); + // Connect handler _handler->connect(this, SIGNAL(startDownloading()), SLOT(download())); _handler->connect(_handler, SIGNAL(doneDownloading()), SLOT(update())); @@ -106,6 +117,12 @@ void ModelsBrowser::applyFilter(const QString &filter) { _handler->unlockModel(); } +void ModelsBrowser::resizeView() { + for (int i = 0; i < MODEL_METADATA_COUNT; ++i) { + _view.resizeColumnToContents(i); + } +} + void ModelsBrowser::browse() { QDialog dialog; dialog.setWindowTitle("Browse models"); @@ -145,8 +162,6 @@ ModelHandler::ModelHandler(ModelType modelsType, QWidget* parent) : _initiateExit(false), _type(modelsType) { - connect(&_downloader, SIGNAL(done(QNetworkReply::NetworkError)), SLOT(downloadFinished())); - // set headers data QStringList headerData; for (int i = 0; i < MODEL_METADATA_COUNT; ++i) { @@ -156,9 +171,6 @@ ModelHandler::ModelHandler(ModelType modelsType, QWidget* parent) : } void ModelHandler::download() { - // Query models list - queryNewFiles(); - _lock.lockForWrite(); if (_initiateExit) { _lock.unlock(); @@ -169,10 +181,25 @@ void ModelHandler::download() { loadingItem->setEnabled(false); _model.appendRow(loadingItem); _lock.unlock(); + + // Query models list + queryNewFiles(); } void ModelHandler::update() { - // Will be implemented in my next PR + _lock.lockForWrite(); + if (_initiateExit) { + _lock.unlock(); + return; + } + for (int i = 0; i < _model.rowCount(); ++i) { + QUrl url(_model.item(i,0)->data(Qt::UserRole).toString()); + QNetworkAccessManager* accessManager = new QNetworkAccessManager(this); + QNetworkRequest request(url); + accessManager->head(request); + connect(accessManager, SIGNAL(finished(QNetworkReply*)), SLOT(downloadFinished(QNetworkReply*))); + } + _lock.unlock(); } void ModelHandler::exit() { @@ -180,7 +207,6 @@ void ModelHandler::exit() { _initiateExit = true; // Disconnect everything - _downloader.disconnect(); disconnect(); thread()->disconnect(); @@ -191,12 +217,16 @@ void ModelHandler::exit() { _lock.unlock(); } -void ModelHandler::downloadFinished() { - if (_downloader.getData().startsWith("readAll(); + + if (!data.isEmpty()) { + parseXML(data); } else { - qDebug() << _downloader.getData(); + parseHeaders(reply); } + reply->deleteLater(); + sender()->deleteLater(); } void ModelHandler::queryNewFiles(QString marker) { @@ -219,7 +249,11 @@ void ModelHandler::queryNewFiles(QString marker) { // Download url.setQuery(query); - _downloader.download(url); + QNetworkAccessManager* accessManager = new QNetworkAccessManager(this); + QNetworkRequest request(url); + accessManager->get(request); + connect(accessManager, SIGNAL(finished(QNetworkReply*)), SLOT(downloadFinished(QNetworkReply*))); + } bool ModelHandler::parseXML(QByteArray xmlFile) { @@ -266,18 +300,9 @@ bool ModelHandler::parseXML(QByteArray xmlFile) { QList model; model << new QStandardItem(QFileInfo(xml.text().toString()).baseName()); model.first()->setData(PUBLIC_URL + "/" + xml.text().toString(), Qt::UserRole); - - // Rand properties for now (Will be taken out in the next PR) - static QString creator[] = {"Ryan", "Philip", "Andzrej"}; - static QString type[] = {"human", "beast", "pet", "elfe"}; - static QString gender[] = {"male", "female", "none"}; - model << new QStandardItem(creator[randIntInRange(0, 2)]); - model << new QStandardItem(QDate(randIntInRange(2013, 2014), - randIntInRange(1, 12), - randIntInRange(1, 30)).toString()); - model << new QStandardItem(type[randIntInRange(0, 3)]); - model << new QStandardItem(gender[randIntInRange(0, 2)]); - //////////////////////////////////////////////////////////// + for (int i = 1; i < MODEL_METADATA_COUNT; ++i) { + model << new QStandardItem(); + } _model.appendRow(model); } @@ -312,9 +337,32 @@ bool ModelHandler::parseXML(QByteArray xmlFile) { _lock.unlock(); if (!truncated) { - qDebug() << "Emitting..."; emit doneDownloading(); } return true; -} \ No newline at end of file +} + +bool ModelHandler::parseHeaders(QNetworkReply* reply) { + _lock.lockForWrite(); + + QList items = _model.findItems(QFileInfo(reply->url().toString()).baseName()); + if (items.isEmpty() || items.first()->text() == DO_NOT_MODIFY_TAG) { + return false; + } + + for (int i = 0; i < MODEL_METADATA_COUNT; ++i) { + for (int k = 1; k < reply->rawHeaderPairs().count(); ++k) { + QString key = reply->rawHeaderPairs().at(k).first.data(); + QString item = reply->rawHeaderPairs().at(k).second.data(); + if (key == propertiesIds[i]) { + _model.item(_model.indexFromItem(items.first()).row(), i)->setText(item); + } + } + } + _lock.unlock(); + + emit updated(); + return true; +} + diff --git a/interface/src/ui/ModelsBrowser.h b/interface/src/ui/ModelsBrowser.h index 9bc239ba18..30320de1c1 100644 --- a/interface/src/ui/ModelsBrowser.h +++ b/interface/src/ui/ModelsBrowser.h @@ -9,13 +9,10 @@ #ifndef __hifi__ModelsBrowser__ #define __hifi__ModelsBrowser__ -#include -#include -#include -#include #include +#include +#include -#include "FileDownloader.h" enum ModelType { Head, @@ -33,7 +30,7 @@ public: signals: void doneDownloading(); - void doneUpdating(); + void updated(); public slots: void download(); @@ -41,17 +38,17 @@ public slots: void exit(); private slots: - void downloadFinished(); + void downloadFinished(QNetworkReply* reply); private: bool _initiateExit; ModelType _type; - FileDownloader _downloader; QReadWriteLock _lock; QStandardItemModel _model; void queryNewFiles(QString marker = QString()); bool parseXML(QByteArray xmlFile); + bool parseHeaders(QNetworkReply* reply); }; @@ -71,6 +68,7 @@ public slots: private slots: void applyFilter(const QString& filter); + void resizeView(); private: ModelHandler* _handler; diff --git a/libraries/shared/src/FileDownloader.cpp b/libraries/shared/src/FileDownloader.cpp deleted file mode 100644 index 8b13b129fe..0000000000 --- a/libraries/shared/src/FileDownloader.cpp +++ /dev/null @@ -1,45 +0,0 @@ -// -// FileDownloader.cpp -// hifi -// -// Created by Clement Brisset on 3/14/14. -// Copyright (c) 2014 HighFidelity, Inc. All rights reserved. -// -// - -#include -#include -#include -#include - -#include "FileDownloader.h" - -FileDownloader::FileDownloader(QObject* parent) : QObject(parent) { - connect(&_networkAccessManager, SIGNAL(finished(QNetworkReply*)), SLOT(processReply(QNetworkReply*))); -} - -void FileDownloader::download(const QUrl& dataURL, QNetworkAccessManager::Operation operation) { - QNetworkRequest request(dataURL); - - _downloadedData.clear(); - switch (operation) { - case QNetworkAccessManager::GetOperation: - _networkAccessManager.get(request); - break; - case QNetworkAccessManager::HeadOperation: - _networkAccessManager.head(request); - break; - default: - emit done(QNetworkReply::ProtocolInvalidOperationError); - break; - } -} - -void FileDownloader::processReply(QNetworkReply *reply) { - if (reply->error() == QNetworkReply::NoError) { - _downloadedData = reply->readAll(); - } - - reply->deleteLater(); - emit done(reply->error()); -} \ No newline at end of file diff --git a/libraries/shared/src/FileDownloader.h b/libraries/shared/src/FileDownloader.h deleted file mode 100644 index ad1351a575..0000000000 --- a/libraries/shared/src/FileDownloader.h +++ /dev/null @@ -1,41 +0,0 @@ -// -// FileDownloader.h -// hifi -// -// Created by Clement Brisset on 3/14/14. -// Copyright (c) 2014 HighFidelity, Inc. All rights reserved. -// -// - -#ifndef __hifi__FileDownloader__ -#define __hifi__FileDownloader__ - -#include -#include -#include -#include - -class FileDownloader : public QObject { - Q_OBJECT - -public: - FileDownloader(QObject* parent = NULL); - QByteArray getData() const { return _downloadedData; } - - -signals: - void done(QNetworkReply::NetworkError error); - -public slots: - void download(const QUrl& dataURL, QNetworkAccessManager::Operation operation = QNetworkAccessManager::GetOperation); - -private slots: - void processReply(QNetworkReply* reply); - -private: - QNetworkAccessManager _networkAccessManager; - QByteArray _downloadedData; -}; - - -#endif /* defined(__hifi__FileDownloader__) */ From cf20c448a3100ab1ca51bbee858b4f15d7d70d6f Mon Sep 17 00:00:00 2001 From: Atlante45 Date: Wed, 2 Apr 2014 16:46:03 -0700 Subject: [PATCH 2/3] Few tweaks before PR --- interface/src/ui/ModelsBrowser.cpp | 20 ++++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) diff --git a/interface/src/ui/ModelsBrowser.cpp b/interface/src/ui/ModelsBrowser.cpp index e128d047ef..276fdd24c1 100644 --- a/interface/src/ui/ModelsBrowser.cpp +++ b/interface/src/ui/ModelsBrowser.cpp @@ -54,7 +54,7 @@ static const QString propertiesIds[MODEL_METADATA_COUNT] = { DO_NOT_MODIFY_TAG, "Type", "Gender", - "x-amz-request-id", + "Creator", "Last-Modified" }; @@ -97,7 +97,7 @@ void ModelsBrowser::applyFilter(const QString &filter) { for (int k = 0; k < filters.count(); ++k) { match = false; for (int j = 0; j < MODEL_METADATA_COUNT; ++j) { - if (model->item(i, j)->text().contains(filters.at(k))) { + if (model->item(i, j)->text().contains(filters.at(k), Qt::CaseInsensitive)) { match = true; break; } @@ -359,6 +359,22 @@ bool ModelHandler::parseHeaders(QNetworkReply* reply) { _model.item(_model.indexFromItem(items.first()).row(), i)->setText(item); } } + + // Rand properties for now (Will be taken out when we have real metadata on the server) + if (_model.item(_model.indexFromItem(items.first()).row(), i)->text().isEmpty()) { + if (i == CREATOR) { + static QString creator[] = {"Ryan", "Philip", "Andzrej", "Phteven", "Brad"}; + _model.item(_model.indexFromItem(items.first()).row(), i)->setText(creator[randIntInRange(0, 4)]); + } else if (i == TYPE) { + static QString type[] = {"human", "beast", "pet", "elfe"}; + _model.item(_model.indexFromItem(items.first()).row(), i)->setText(type[randIntInRange(0, 3)]); + } else if (i == GENDER) { + static QString gender[] = {"male", "female", "none"}; + _model.item(_model.indexFromItem(items.first()).row(), i)->setText(gender[randIntInRange(0, 2)]); + } + } + //////////////////////////////////////////////////////////// + } _lock.unlock(); From c2f0545d96c3af7fc1c1f047a3b42d66d0a58826 Mon Sep 17 00:00:00 2001 From: Atlante45 Date: Wed, 2 Apr 2014 17:12:11 -0700 Subject: [PATCH 3/3] Setup for actual metadata --- interface/src/ui/ModelsBrowser.cpp | 37 ++++++++++-------------------- 1 file changed, 12 insertions(+), 25 deletions(-) diff --git a/interface/src/ui/ModelsBrowser.cpp b/interface/src/ui/ModelsBrowser.cpp index 276fdd24c1..616aba3881 100644 --- a/interface/src/ui/ModelsBrowser.cpp +++ b/interface/src/ui/ModelsBrowser.cpp @@ -36,26 +36,29 @@ static const QString DO_NOT_MODIFY_TAG = "DoNotModify"; enum ModelMetaData { NAME, - TYPE, - GENDER, CREATOR, - UPLOAD_DATE, + DATE_ADDED, + TOTAL_SIZE, + POLY_NUM, + TAGS, MODEL_METADATA_COUNT }; static const QString propertiesNames[MODEL_METADATA_COUNT] = { "Name", - "Type", - "Gender", "Creator", - "Last Modified" + "Date Added", + "Total Size", + "Poly#", + "Tags" }; static const QString propertiesIds[MODEL_METADATA_COUNT] = { DO_NOT_MODIFY_TAG, - "Type", - "Gender", "Creator", - "Last-Modified" + "Date-Added", + "Total-Size", + "Poly-Num", + "Tags" }; ModelsBrowser::ModelsBrowser(ModelType modelsType, QWidget* parent) : @@ -359,22 +362,6 @@ bool ModelHandler::parseHeaders(QNetworkReply* reply) { _model.item(_model.indexFromItem(items.first()).row(), i)->setText(item); } } - - // Rand properties for now (Will be taken out when we have real metadata on the server) - if (_model.item(_model.indexFromItem(items.first()).row(), i)->text().isEmpty()) { - if (i == CREATOR) { - static QString creator[] = {"Ryan", "Philip", "Andzrej", "Phteven", "Brad"}; - _model.item(_model.indexFromItem(items.first()).row(), i)->setText(creator[randIntInRange(0, 4)]); - } else if (i == TYPE) { - static QString type[] = {"human", "beast", "pet", "elfe"}; - _model.item(_model.indexFromItem(items.first()).row(), i)->setText(type[randIntInRange(0, 3)]); - } else if (i == GENDER) { - static QString gender[] = {"male", "female", "none"}; - _model.item(_model.indexFromItem(items.first()).row(), i)->setText(gender[randIntInRange(0, 2)]); - } - } - //////////////////////////////////////////////////////////// - } _lock.unlock();