Merge branch 'develop' of github.com:MultiMC/MultiMC5 into feature_news

Conflicts:
	CMakeLists.txt
This commit is contained in:
Andrew
2013-12-15 15:01:34 -06:00
45 changed files with 796 additions and 541 deletions

View File

@ -149,7 +149,7 @@ public:
*/
virtual SettingsObject &settings() const;
/// returns a valid update task if update is needed, NULL otherwise
/// returns a valid update task
virtual std::shared_ptr<Task> doUpdate(bool only_prepare) = 0;
/// returns a valid minecraft process, ready for launch with the given account.

View File

@ -152,8 +152,17 @@ QStringList OneSixInstance::processMinecraftArgs(MojangAccountPtr account)
token_mapping["game_directory"] = absRootDir;
QString absAssetsDir = QDir("assets/").absolutePath();
token_mapping["game_assets"] = reconstructAssets(d->version).absolutePath();
//TODO: this is something new and not even fully implemented in the vanilla launcher.
token_mapping["user_properties"] = "{ }";
auto user = account->user();
QJsonObject userAttrs;
for(auto key: user.properties.keys())
{
auto array = QJsonArray::fromStringList(user.properties.values(key));
userAttrs.insert(key, array);
}
QJsonDocument value(userAttrs);
token_mapping["user_properties"] = value.toJson(QJsonDocument::Compact);
token_mapping["user_type"] = account->currentProfile()->legacy ? "legacy" : "mojang";
// 1.7.3+ assets tokens
token_mapping["assets_root"] = absAssetsDir;

View File

@ -54,11 +54,9 @@ void OneSixUpdate::executeTask()
if (m_only_prepare)
{
if (m_inst->shouldUpdate())
{
emitFailed("Unable to update instance in offline mode.");
return;
}
/*
* FIXME: in offline mode, do not proceed!
*/
setStatus("Testing the Java installation.");
QString java_path = m_inst->settings().get("JavaPath").toString();
@ -243,11 +241,13 @@ void OneSixUpdate::assetIndexFinished()
auto objectDL = MD5EtagDownload::make(
QUrl("http://" + URLConstants::RESOURCE_BASE + objectName),
objectFile.filePath());
objectDL->m_total_progress = object.size;
dls.append(objectDL);
}
}
if(dls.size())
{
setStatus("Getting the assets files from Mojang...");
auto job = new NetJob("Assets for " + inst->name());
for(auto dl: dls)
job->addNetAction(dl);

View File

@ -68,6 +68,7 @@ MojangAccountPtr MojangAccount::loadFromJson(const QJsonObject &object)
User u;
QJsonObject userStructure = object.value("user").toObject();
u.id = userStructure.value("id").toString();
/*
QJsonObject propMap = userStructure.value("properties").toObject();
for(auto key: propMap.keys())
{
@ -75,6 +76,7 @@ MojangAccountPtr MojangAccount::loadFromJson(const QJsonObject &object)
for(auto value: values)
u.properties.insert(key, value.toString());
}
*/
account->m_user = u;
}
account->m_username = username;
@ -119,6 +121,7 @@ QJsonObject MojangAccount::saveToJson() const
QJsonObject userStructure;
{
userStructure.insert("id", m_user.id);
/*
QJsonObject userAttrs;
for(auto key: m_user.properties.keys())
{
@ -126,6 +129,7 @@ QJsonObject MojangAccount::saveToJson() const
userAttrs.insert(key, array);
}
userStructure.insert("properties", userAttrs);
*/
}
json.insert("user", userStructure);

View File

@ -122,6 +122,11 @@ public: /* queries */
return m_profiles;
}
const User & user()
{
return m_user;
}
//! Get the session ID required for legacy Minecraft versions
QString sessionId() const
{

View File

@ -22,10 +22,12 @@
#include <QJsonArray>
#include <QJsonObject>
#include <QJsonParseError>
#include <QDir>
#include "logger/QsLog.h"
#include "logic/auth/MojangAccount.h"
#include <pathutils.h>
#define ACCOUNT_LIST_FORMAT_VERSION 2
@ -148,9 +150,6 @@ QVariant MojangAccountList::data(const QModelIndex &index, int role) const
case Qt::DisplayRole:
switch (index.column())
{
case ActiveColumn:
return account == m_activeAccount;
case NameColumn:
return account->username();
@ -164,6 +163,13 @@ QVariant MojangAccountList::data(const QModelIndex &index, int role) const
case PointerRole:
return qVariantFromValue(account);
case Qt::CheckStateRole:
switch (index.column())
{
case ActiveColumn:
return account == m_activeAccount;
}
default:
return QVariant();
}
@ -212,6 +218,36 @@ int MojangAccountList::columnCount(const QModelIndex &parent) const
return 2;
}
Qt::ItemFlags MojangAccountList::flags(const QModelIndex &index) const
{
if (index.row() < 0 || index.row() >= rowCount(index) || !index.isValid())
{
return Qt::NoItemFlags;
}
return Qt::ItemIsUserCheckable | Qt::ItemIsEnabled | Qt::ItemIsSelectable;
}
bool MojangAccountList::setData(const QModelIndex &index, const QVariant &value, int role)
{
if (index.row() < 0 || index.row() >= rowCount(index) || !index.isValid())
{
return false;
}
if(role == Qt::CheckStateRole)
{
if(value == Qt::Checked)
{
MojangAccountPtr account = this->at(index.row());
this->setActiveAccount(account->username());
}
}
emit dataChanged(index, index);
return true;
}
void MojangAccountList::updateListData(QList<MojangAccountPtr> versions)
{
beginResetModel();
@ -311,6 +347,18 @@ bool MojangAccountList::saveList(const QString &filePath)
return false;
}
// make sure the parent folder exists
if(!ensureFilePathExists(path))
return false;
// make sure the file wasn't overwritten with a folder before (fixes a bug)
QFileInfo finfo(path);
if(finfo.isDir())
{
QDir badDir(path);
badDir.removeRecursively();
}
QLOG_INFO() << "Writing account list to" << path;
QLOG_DEBUG() << "Building JSON data structure.";
@ -366,3 +414,13 @@ void MojangAccountList::setListFilePath(QString path, bool autosave)
m_listFilePath = path;
m_autosave = autosave;
}
bool MojangAccountList::anyAccountIsValid()
{
for(auto account:m_accounts)
{
if(account->accountStatus() != NotVerified)
return true;
}
return false;
}

View File

@ -64,6 +64,8 @@ public:
virtual QVariant headerData(int section, Qt::Orientation orientation, int role) const;
virtual int rowCount(const QModelIndex &parent) const;
virtual int columnCount(const QModelIndex &parent) const;
virtual Qt::ItemFlags flags(const QModelIndex &index) const;
virtual bool setData(const QModelIndex &index, const QVariant &value, int role);
/*!
* Adds a the given Mojang account to the account list.
@ -124,6 +126,11 @@ public:
* If the username given is an empty string, sets the active account to nothing.
*/
virtual void setActiveAccount(const QString &username);
/*!
* Returns true if any of the account is at least Validated
*/
bool anyAccountIsValid();
signals:
/*!

View File

@ -162,23 +162,17 @@ bool AuthenticateTask::processResponse(QJsonObject responseData)
}
// this is what the vanilla launcher passes to the userProperties launch param
// doesn't seem to be used for anything so far? I don't get any of this data on my account
// (peterixxx)
// is it a good idea to log this?
if (responseData.contains("user"))
{
User u;
auto obj = responseData.value("user").toObject();
u.id = obj.value("id").toString();
QLOG_DEBUG() << "User ID: " << u.id ;
auto propArray = obj.value("properties").toArray();
QLOG_DEBUG() << "User Properties: ";
for (auto prop : propArray)
{
auto propTuple = prop.toObject();
auto name = propTuple.value("name").toString();
auto value = propTuple.value("value").toString();
QLOG_DEBUG() << name << " : " << value;
u.properties.insert(name, value);
}
m_account->m_user = u;

View File

@ -112,20 +112,21 @@ bool RefreshTask::processResponse(QJsonObject responseData)
// this is what the vanilla launcher passes to the userProperties launch param
if (responseData.contains("user"))
{
User u;
auto obj = responseData.value("user").toObject();
auto userId = obj.value("id").toString();
u.id = obj.value("id").toString();
auto propArray = obj.value("properties").toArray();
QLOG_DEBUG() << "User ID: " << userId;
QLOG_DEBUG() << "User Properties: ";
for (auto prop : propArray)
{
auto propTuple = prop.toObject();
auto name = propTuple.value("name").toString();
auto value = propTuple.value("value").toString();
QLOG_DEBUG() << name << " : " << value;
u.properties.insert(name, value);
}
m_account->m_user = u;
}
// We've made it through the minefield of possible errors. Return true to indicate that
// we've succeeded.
QLOG_DEBUG() << "Finished reading refresh response.";

View File

@ -36,11 +36,16 @@ const static int GROUP_FILE_FORMAT_VERSION = 1;
InstanceList::InstanceList(const QString &instDir, QObject *parent)
: QAbstractListModel(parent), m_instDir(instDir)
{
connect(MMC, &MultiMC::aboutToQuit, this, &InstanceList::saveGroupList);
if (!QDir::current().exists(m_instDir))
{
QDir::current().mkpath(m_instDir);
}
}
InstanceList::~InstanceList()
{
saveGroupList();
}
int InstanceList::rowCount(const QModelIndex &parent) const
@ -112,6 +117,11 @@ void InstanceList::groupChanged()
saveGroupList();
}
QStringList InstanceList::getGroups()
{
return m_groups.toList();
}
void InstanceList::saveGroupList()
{
QString groupFileName = m_instDir + "/instgroups.json";
@ -121,7 +131,7 @@ void InstanceList::saveGroupList()
if (!groupFile.open(QIODevice::WriteOnly | QIODevice::Truncate))
{
// An error occurred. Ignore it.
QLOG_ERROR() << "Failed to read instance group file.";
QLOG_ERROR() << "Failed to save instance group file.";
return;
}
QTextStream out(&groupFile);
@ -132,6 +142,10 @@ void InstanceList::saveGroupList()
QString group = instance->group();
if (group.isEmpty())
continue;
// keep a list/set of groups for choosing
m_groups.insert(group);
if (!groupMap.count(group))
{
QSet<QString> set;
@ -248,6 +262,9 @@ void InstanceList::loadGroupList(QMap<QString, QString> &groupMap)
continue;
}
// keep a list/set of groups for choosing
m_groups.insert(groupName);
// Iterate through the list of instances in the group.
QJsonArray instancesArray = groupObj.value("instances").toArray();

View File

@ -17,6 +17,7 @@
#include <QObject>
#include <QAbstractListModel>
#include <QSet>
#include "categorizedsortfilterproxymodel.h"
#include <QIcon>
@ -29,6 +30,9 @@ class InstanceList : public QAbstractListModel
Q_OBJECT
private:
void loadGroupList(QMap<QString, QString> &groupList);
private
slots:
void saveGroupList();
public:
@ -94,6 +98,9 @@ public:
InstancePtr getInstanceById(QString id) const;
QModelIndex getInstanceIndexById(const QString &id) const;
// FIXME: instead of iterating through all instances and forming a set, keep the set around
QStringList getGroups();
signals:
void dataIsInvalid();
@ -113,6 +120,7 @@ private:
protected:
QString m_instDir;
QList<InstancePtr> m_instances;
QSet<QString> m_groups;
};
class InstanceProxyModel : public KCategorizedSortFilterProxyModel

View File

@ -42,7 +42,9 @@ void ByteArrayDownload::start()
void ByteArrayDownload::downloadProgress(qint64 bytesReceived, qint64 bytesTotal)
{
emit progress(index_within_job, bytesReceived, bytesTotal);
m_total_progress = bytesTotal;
m_progress = bytesReceived;
emit progress(m_index_within_job, bytesReceived, bytesTotal);
}
void ByteArrayDownload::downloadError(QNetworkReply::NetworkError error)
@ -62,14 +64,14 @@ void ByteArrayDownload::downloadFinished()
m_status = Job_Finished;
m_data = m_reply->readAll();
m_reply.reset();
emit succeeded(index_within_job);
emit succeeded(m_index_within_job);
return;
}
// else the download failed
else
{
m_reply.reset();
emit failed(index_within_job);
emit failed(m_index_within_job);
return;
}
}

View File

@ -35,14 +35,14 @@ void CacheDownload::start()
{
if (!m_entry->stale)
{
emit succeeded(index_within_job);
emit succeeded(m_index_within_job);
return;
}
m_output_file.setFileName(m_target_path);
// if there already is a file and md5 checking is in effect and it can be opened
if (!ensureFilePathExists(m_target_path))
{
emit failed(index_within_job);
emit failed(m_index_within_job);
return;
}
QLOG_INFO() << "Downloading " << m_url.toString();
@ -69,7 +69,9 @@ void CacheDownload::start()
void CacheDownload::downloadProgress(qint64 bytesReceived, qint64 bytesTotal)
{
emit progress(index_within_job, bytesReceived, bytesTotal);
m_total_progress = bytesTotal;
m_progress = bytesReceived;
emit progress(m_index_within_job, bytesReceived, bytesTotal);
}
void CacheDownload::downloadError(QNetworkReply::NetworkError error)
@ -116,7 +118,7 @@ void CacheDownload::downloadFinished()
MMC->metacache()->updateEntry(m_entry);
m_reply.reset();
emit succeeded(index_within_job);
emit succeeded(m_index_within_job);
return;
}
// else the download failed
@ -125,7 +127,7 @@ void CacheDownload::downloadFinished()
m_output_file.close();
m_output_file.remove();
m_reply.reset();
emit failed(index_within_job);
emit failed(m_index_within_job);
return;
}
}
@ -140,7 +142,7 @@ void CacheDownload::downloadReadyRead()
* Can't open the file... the job failed
*/
m_reply->abort();
emit failed(index_within_job);
emit failed(m_index_within_job);
return;
}
}

View File

@ -68,7 +68,7 @@ void ForgeMirrors::deferToFixedList()
"https://www.creeperhost.net/link.php?id=1",
"http://new.creeperrepo.net/forge/maven/"});
injectDownloads();
emit succeeded(index_within_job);
emit succeeded(m_index_within_job);
}
void ForgeMirrors::parseMirrorList()
@ -88,7 +88,7 @@ void ForgeMirrors::parseMirrorList()
if(!m_mirrors.size())
deferToFixedList();
injectDownloads();
emit succeeded(index_within_job);
emit succeeded(m_index_within_job);
}
void ForgeMirrors::injectDownloads()
@ -108,7 +108,9 @@ void ForgeMirrors::injectDownloads()
void ForgeMirrors::downloadProgress(qint64 bytesReceived, qint64 bytesTotal)
{
emit progress(index_within_job, bytesReceived, bytesTotal);
m_total_progress = bytesTotal;
m_progress = bytesReceived;
emit progress(m_index_within_job, bytesReceived, bytesTotal);
}
void ForgeMirrors::downloadReadyRead()

View File

@ -44,20 +44,20 @@ void ForgeXzDownload::start()
if (!m_entry->stale)
{
m_status = Job_Finished;
emit succeeded(index_within_job);
emit succeeded(m_index_within_job);
return;
}
// can we actually create the real, final file?
if (!ensureFilePathExists(m_target_path))
{
m_status = Job_Failed;
emit failed(index_within_job);
emit failed(m_index_within_job);
return;
}
if (m_mirrors.empty())
{
m_status = Job_Failed;
emit failed(index_within_job);
emit failed(m_index_within_job);
return;
}
@ -80,7 +80,9 @@ void ForgeXzDownload::start()
void ForgeXzDownload::downloadProgress(qint64 bytesReceived, qint64 bytesTotal)
{
emit progress(index_within_job, bytesReceived, bytesTotal);
m_total_progress = bytesTotal;
m_progress = bytesReceived;
emit progress(m_index_within_job, bytesReceived, bytesTotal);
}
void ForgeXzDownload::downloadError(QNetworkReply::NetworkError error)
@ -100,7 +102,7 @@ void ForgeXzDownload::failAndTryNextMirror()
m_mirror_index = next;
updateUrl();
emit failed(index_within_job);
emit failed(m_index_within_job);
}
void ForgeXzDownload::updateUrl()
@ -148,7 +150,7 @@ void ForgeXzDownload::downloadFinished()
m_status = Job_Failed;
m_pack200_xz_file.remove();
m_reply.reset();
emit failed(index_within_job);
emit failed(m_index_within_job);
return;
}
}
@ -175,7 +177,7 @@ void ForgeXzDownload::downloadReadyRead()
* Can't open the file... the job failed
*/
m_reply->abort();
emit failed(index_within_job);
emit failed(m_index_within_job);
return;
}
}
@ -347,5 +349,5 @@ void ForgeXzDownload::decompressAndInstall()
MMC->metacache()->updateEntry(m_entry);
m_reply.reset();
emit succeeded(index_within_job);
emit succeeded(m_index_within_job);
}

View File

@ -44,7 +44,7 @@ void MD5EtagDownload::start()
if (m_check_md5 && hash == m_expected_md5)
{
QLOG_INFO() << "Skipping " << m_url.toString() << ": md5 match.";
emit succeeded(index_within_job);
emit succeeded(m_index_within_job);
return;
}
else
@ -54,7 +54,7 @@ void MD5EtagDownload::start()
}
if (!ensureFilePathExists(filename))
{
emit failed(index_within_job);
emit failed(m_index_within_job);
return;
}
@ -68,7 +68,7 @@ void MD5EtagDownload::start()
// Plus, this way, we don't end up starting a download for a file we can't open.
if (!m_output_file.open(QIODevice::WriteOnly))
{
emit failed(index_within_job);
emit failed(m_index_within_job);
return;
}
@ -86,7 +86,9 @@ void MD5EtagDownload::start()
void MD5EtagDownload::downloadProgress(qint64 bytesReceived, qint64 bytesTotal)
{
emit progress(index_within_job, bytesReceived, bytesTotal);
m_total_progress = bytesTotal;
m_progress = bytesReceived;
emit progress(m_index_within_job, bytesReceived, bytesTotal);
}
void MD5EtagDownload::downloadError(QNetworkReply::NetworkError error)
@ -107,7 +109,7 @@ void MD5EtagDownload::downloadFinished()
QLOG_INFO() << "Finished " << m_url.toString() << " got " << m_reply->rawHeader("ETag").constData();
m_reply.reset();
emit succeeded(index_within_job);
emit succeeded(m_index_within_job);
return;
}
// else the download failed
@ -115,7 +117,7 @@ void MD5EtagDownload::downloadFinished()
{
m_output_file.close();
m_reply.reset();
emit failed(index_within_job);
emit failed(m_index_within_job);
return;
}
}
@ -130,7 +132,7 @@ void MD5EtagDownload::downloadReadyRead()
* Can't open the file... the job failed
*/
m_reply->abort();
emit failed(index_within_job);
emit failed(m_index_within_job);
return;
}
}

View File

@ -38,6 +38,19 @@ protected:
public:
virtual ~NetAction() {};
public:
virtual qint64 totalProgress() const
{
return m_total_progress;
}
virtual qint64 currentProgress() const
{
return m_progress;
}
virtual qint64 numberOfFailures() const
{
return m_failures;
}
public:
/// the network reply
std::shared_ptr<QNetworkReply> m_reply;
@ -46,10 +59,16 @@ public:
QUrl m_url;
/// The file's status
JobStatus m_status;
JobStatus m_status = Job_NotStarted;
/// index within the parent job
int index_within_job = 0;
int m_index_within_job = 0;
qint64 m_progress = 0;
qint64 m_total_progress = 1;
/// number of failures up to this point
int m_failures = 0;
signals:
void started(int index);

View File

@ -36,10 +36,16 @@ public:
template <typename T> bool addNetAction(T action)
{
NetActionPtr base = std::static_pointer_cast<NetAction>(action);
base->index_within_job = downloads.size();
base->m_index_within_job = downloads.size();
downloads.append(action);
parts_progress.append(part_info());
total_progress++;
part_info pi;
{
pi.current_progress = base->currentProgress();
pi.total_progress = base->totalProgress();
pi.failures = base->numberOfFailures();
}
parts_progress.append(pi);
total_progress += pi.total_progress;
// if this is already running, the action needs to be started right away!
if (isRunning())
{

View File

@ -78,7 +78,9 @@ bool PasteUpload::parseResult(QJsonDocument doc, QString *parseError)
parseError = new QString(object.value("error").toString());
return false;
}
// FIXME: not the place for GUI things.
QString pasteUrl = object.value("paste").toObject().value("link").toString();
QDesktopServices::openUrl(pasteUrl);
return true;
}

View File

@ -1,175 +0,0 @@
/* Copyright 2013 MultiMC Contributors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "S3ListBucket.h"
#include "MultiMC.h"
#include "logger/QsLog.h"
#include <QUrlQuery>
#include <qxmlstream.h>
#include <QDomDocument>
inline QDomElement getDomElementByTagName(QDomElement parent, QString tagname)
{
QDomNodeList elementList = parent.elementsByTagName(tagname);
if (elementList.count())
return elementList.at(0).toElement();
else
return QDomElement();
}
S3ListBucket::S3ListBucket(QUrl url) : NetAction()
{
m_url = url;
m_status = Job_NotStarted;
}
void S3ListBucket::start()
{
QUrl finalUrl = m_url;
if (current_marker.size())
{
QUrlQuery query;
query.addQueryItem("marker", current_marker);
finalUrl.setQuery(query);
}
QNetworkRequest request(finalUrl);
request.setHeader(QNetworkRequest::UserAgentHeader, "MultiMC/5.0 (Uncached)");
auto worker = MMC->qnam();
QNetworkReply *rep = worker->get(request);
m_reply = std::shared_ptr<QNetworkReply>(rep);
connect(rep, SIGNAL(downloadProgress(qint64, qint64)),
SLOT(downloadProgress(qint64, qint64)));
connect(rep, SIGNAL(finished()), SLOT(downloadFinished()));
connect(rep, SIGNAL(error(QNetworkReply::NetworkError)),
SLOT(downloadError(QNetworkReply::NetworkError)));
connect(rep, SIGNAL(readyRead()), SLOT(downloadReadyRead()));
}
void S3ListBucket::downloadProgress(qint64 bytesReceived, qint64 bytesTotal)
{
emit progress(index_within_job, bytesSoFar + bytesReceived, bytesSoFar + bytesTotal);
}
void S3ListBucket::downloadError(QNetworkReply::NetworkError error)
{
// error happened during download.
QLOG_ERROR() << "Error getting URL:" << m_url.toString().toLocal8Bit()
<< "Network error: " << error;
m_status = Job_Failed;
}
void S3ListBucket::processValidReply()
{
QLOG_TRACE() << "GOT: " << m_url.toString() << " marker:" << current_marker;
auto readContents = [&](QXmlStreamReader & xml)
{
QString Key, ETag, Size;
while (!(xml.tokenType() == QXmlStreamReader::EndElement && xml.name() == "Contents"))
{
if (xml.tokenType() == QXmlStreamReader::StartElement)
{
if (xml.name() == "Key")
{
Key = xml.readElementText();
}
if (xml.name() == "ETag")
{
ETag = xml.readElementText();
}
if (xml.name() == "Size")
{
Size = xml.readElementText();
}
}
xml.readNext();
}
if (xml.error() != QXmlStreamReader::NoError)
return;
objects.append({Key, ETag, Size.toLongLong()});
};
// nothing went wrong...
QByteArray ba = m_reply->readAll();
QString xmlErrorMsg;
bool is_truncated = false;
QXmlStreamReader xml(ba);
while (!xml.atEnd() && !xml.hasError())
{
/* Read next element.*/
QXmlStreamReader::TokenType token = xml.readNext();
/* If token is just StartDocument, we'll go to next.*/
if (token == QXmlStreamReader::StartDocument)
{
continue;
}
if (token == QXmlStreamReader::StartElement)
{
/* If it's named person, we'll dig the information from there.*/
if (xml.name() == "Contents")
{
readContents(xml);
}
else if (xml.name() == "IsTruncated")
{
is_truncated = (xml.readElementText() == "true");
}
}
}
if (xml.hasError())
{
QLOG_ERROR() << "Failed to process s3.amazonaws.com/Minecraft.Resources. XML error:"
<< xml.errorString() << ba;
emit failed(index_within_job);
return;
}
if (is_truncated)
{
current_marker = objects.last().Key;
bytesSoFar += m_reply->size();
m_reply.reset();
start();
}
else
{
m_status = Job_Finished;
m_reply.reset();
emit succeeded(index_within_job);
}
return;
}
void S3ListBucket::downloadFinished()
{
// if the download succeeded
if (m_status != Job_Failed)
{
processValidReply();
}
// else the download failed
else
{
m_reply.reset();
emit failed(index_within_job);
return;
}
}
void S3ListBucket::downloadReadyRead()
{
// ~_~
}

View File

@ -1,57 +0,0 @@
/* Copyright 2013 MultiMC Contributors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#pragma once
#include "NetAction.h"
struct S3Object
{
QString Key;
QString ETag;
qlonglong size;
};
typedef std::shared_ptr<class S3ListBucket> S3ListBucketPtr;
class S3ListBucket : public NetAction
{
Q_OBJECT
public:
S3ListBucket(QUrl url);
static S3ListBucketPtr make(QUrl url)
{
return S3ListBucketPtr(new S3ListBucket(url));
}
public:
QList<S3Object> objects;
public
slots:
virtual void start() override;
protected
slots:
virtual void downloadProgress(qint64 bytesReceived, qint64 bytesTotal) override;
virtual void downloadError(QNetworkReply::NetworkError error) override;
virtual void downloadFinished() override;
virtual void downloadReadyRead() override;
private:
void processValidReply();
private:
qint64 bytesSoFar = 0;
QString current_marker;
};