summaryrefslogtreecommitdiff
path: root/src/downloadmanager.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/downloadmanager.cpp')
-rw-r--r--src/downloadmanager.cpp432
1 files changed, 279 insertions, 153 deletions
diff --git a/src/downloadmanager.cpp b/src/downloadmanager.cpp
index 31d8bcec..5200bb4f 100644
--- a/src/downloadmanager.cpp
+++ b/src/downloadmanager.cpp
@@ -27,6 +27,7 @@ along with Mod Organizer. If not, see <http://www.gnu.org/licenses/>.
#include "json.h"
#include "selectiondialog.h"
#include <utility.h>
+#include <bbcode.h>
#include <QTimer>
#include <QFileInfo>
#include <QRegExp>
@@ -49,7 +50,7 @@ static const char UNFINISHED[] = ".unfinished";
unsigned int DownloadManager::DownloadInfo::s_NextDownloadID = 1U;
-DownloadManager::DownloadInfo *DownloadManager::DownloadInfo::createNew(const NexusInfo &nexusInfo, int modID, int fileID, const QStringList &URLs)
+DownloadManager::DownloadInfo *DownloadManager::DownloadInfo::createNew(const ModRepositoryFileInfo *fileInfo, const QStringList &URLs)
{
DownloadInfo *info = new DownloadInfo;
info->m_DownloadID = s_NextDownloadID++;
@@ -57,9 +58,7 @@ DownloadManager::DownloadInfo *DownloadManager::DownloadInfo::createNew(const Ne
info->m_PreResumeSize = 0LL;
info->m_Progress = 0;
info->m_ResumePos = 0;
- info->m_ModID = modID;
- info->m_FileID = fileID;
- info->m_NexusInfo = nexusInfo;
+ info->m_FileInfo = new ModRepositoryFileInfo(*fileInfo);
info->m_Urls = URLs;
info->m_CurrentUrl = 0;
info->m_Tries = AUTOMATIC_RETRIES;
@@ -104,17 +103,28 @@ DownloadManager::DownloadInfo *DownloadManager::DownloadInfo::createFromMeta(con
info->m_Output.setFileName(filePath);
info->m_TotalSize = QFileInfo(filePath).size();
info->m_PreResumeSize = info->m_TotalSize;
- info->m_ModID = metaFile.value("modID", 0).toInt();
- info->m_FileID = metaFile.value("fileID", 0).toInt();
info->m_CurrentUrl = 0;
info->m_Urls = metaFile.value("url", "").toString().split(";");
info->m_Tries = 0;
info->m_TaskProgressId = TaskProgressManager::instance().getId();
- info->m_NexusInfo.m_Name = metaFile.value("name", 0).toString();
- info->m_NexusInfo.m_ModName = metaFile.value("modName", "").toString();
- info->m_NexusInfo.m_Version = metaFile.value("version", 0).toString();
- info->m_NexusInfo.m_NewestVersion = metaFile.value("newestVersion", "").toString();
- info->m_NexusInfo.m_Category = metaFile.value("category", 0).toInt();
+ int modID = metaFile.value("modID", 0).toInt();
+ int fileID = metaFile.value("fileID", 0).toInt();
+ info->m_FileInfo = new ModRepositoryFileInfo(modID, fileID);
+ info->m_FileInfo->name = metaFile.value("name", "").toString();
+ if (info->m_FileInfo->name == "0") {
+ // bug in earlier version
+ info->m_FileInfo->name = "";
+ }
+ info->m_FileInfo->modName = metaFile.value("modName", "").toString();
+ info->m_FileInfo->modID = modID;
+ info->m_FileInfo->fileID = fileID;
+ info->m_FileInfo->description = metaFile.value("description").toString();
+ info->m_FileInfo->version.parse(metaFile.value("version", "0").toString());
+ info->m_FileInfo->newestVersion.parse(metaFile.value("newestVersion", "0").toString());
+ info->m_FileInfo->categoryID = metaFile.value("category", 0).toInt();
+ info->m_FileInfo->fileCategory = metaFile.value("fileCategory", 0).toInt();
+ info->m_FileInfo->repository = metaFile.value("repository", "Nexus").toString();
+ info->m_FileInfo->userData = metaFile.value("userData").toMap();
return info;
}
@@ -138,7 +148,10 @@ void DownloadManager::DownloadInfo::setName(QString newName, bool renameFile)
metaFile.rename(newName.mid(0).append(".meta"));
}
}
- m_Output.setFileName(newName);
+ if (!m_Output.isOpen()) {
+ // can't set file name if it's open
+ m_Output.setFileName(newName);
+ }
}
bool DownloadManager::DownloadInfo::isPausedState()
@@ -243,72 +256,75 @@ void DownloadManager::setShowHidden(bool showHidden)
void DownloadManager::refreshList()
{
- int downloadsBefore = m_ActiveDownloads.size();
+ try {
+ int downloadsBefore = m_ActiveDownloads.size();
- // remove finished downloads
- for (QVector<DownloadInfo*>::iterator Iter = m_ActiveDownloads.begin(); Iter != m_ActiveDownloads.end();) {
- if (((*Iter)->m_State == STATE_READY) || ((*Iter)->m_State == STATE_INSTALLED) || ((*Iter)->m_State == STATE_UNINSTALLED)) {
- delete *Iter;
- Iter = m_ActiveDownloads.erase(Iter);
- } else {
- ++Iter;
+ // remove finished downloads
+ for (QVector<DownloadInfo*>::iterator iter = m_ActiveDownloads.begin(); iter != m_ActiveDownloads.end();) {
+ if (((*iter)->m_State == STATE_READY) || ((*iter)->m_State == STATE_INSTALLED) || ((*iter)->m_State == STATE_UNINSTALLED)) {
+ delete *iter;
+ iter = m_ActiveDownloads.erase(iter);
+ } else {
+ ++iter;
+ }
}
- }
- QStringList nameFilters(m_SupportedExtensions);
- foreach (const QString &extension, m_SupportedExtensions) {
- nameFilters.append("*." + extension);
- }
-
- nameFilters.append(QString("*").append(UNFINISHED));
- QDir dir(QDir::fromNativeSeparators(m_OutputDirectory));
-
- // find orphaned meta files and delete them (sounds cruel but it's better for everyone)
- QStringList orphans;
- QStringList metaFiles = dir.entryList(QStringList() << "*.meta");
- foreach (const QString &metaFile, metaFiles) {
- QString baseFile = metaFile.left(metaFile.length() - 5);
- if (!QFile::exists(dir.absoluteFilePath(baseFile))) {
- orphans.append(dir.absoluteFilePath(metaFile));
+ QStringList nameFilters(m_SupportedExtensions);
+ foreach (const QString &extension, m_SupportedExtensions) {
+ nameFilters.append("*." + extension);
}
- }
- if (orphans.size() > 0) {
- qDebug("%d orphaned meta files will be deleted", orphans.size());
- shellDelete(orphans, true);
- }
- // add existing downloads to list
- foreach (QString file, dir.entryList(nameFilters, QDir::Files, QDir::Time)) {
- bool Exists = false;
- for (QVector<DownloadInfo*>::const_iterator Iter = m_ActiveDownloads.begin(); Iter != m_ActiveDownloads.end() && !Exists; ++Iter) {
- if (QString::compare((*Iter)->m_FileName, file, Qt::CaseInsensitive) == 0) {
- Exists = true;
- } else if (QString::compare(QFileInfo((*Iter)->m_Output.fileName()).fileName(), file, Qt::CaseInsensitive) == 0) {
- Exists = true;
+ nameFilters.append(QString("*").append(UNFINISHED));
+ QDir dir(QDir::fromNativeSeparators(m_OutputDirectory));
+
+ // find orphaned meta files and delete them (sounds cruel but it's better for everyone)
+ QStringList orphans;
+ QStringList metaFiles = dir.entryList(QStringList() << "*.meta");
+ foreach (const QString &metaFile, metaFiles) {
+ QString baseFile = metaFile.left(metaFile.length() - 5);
+ if (!QFile::exists(dir.absoluteFilePath(baseFile))) {
+ orphans.append(dir.absoluteFilePath(metaFile));
}
}
- if (Exists) {
- qDebug("%s exists", qPrintable(file));
- continue;
+ if (orphans.size() > 0) {
+ qDebug("%d orphaned meta files will be deleted", orphans.size());
+ shellDelete(orphans, true);
}
- QString fileName = QDir::fromNativeSeparators(m_OutputDirectory) + "/" + file;
+ // add existing downloads to list
+ foreach (QString file, dir.entryList(nameFilters, QDir::Files, QDir::Time)) {
+ bool Exists = false;
+ for (QVector<DownloadInfo*>::const_iterator Iter = m_ActiveDownloads.begin(); Iter != m_ActiveDownloads.end() && !Exists; ++Iter) {
+ if (QString::compare((*Iter)->m_FileName, file, Qt::CaseInsensitive) == 0) {
+ Exists = true;
+ } else if (QString::compare(QFileInfo((*Iter)->m_Output.fileName()).fileName(), file, Qt::CaseInsensitive) == 0) {
+ Exists = true;
+ }
+ }
+ if (Exists) {
+ continue;
+ }
- DownloadInfo *info = DownloadInfo::createFromMeta(fileName, m_ShowHidden);
- if (info != NULL) {
- m_ActiveDownloads.push_front(info);
+ QString fileName = QDir::fromNativeSeparators(m_OutputDirectory) + "/" + file;
+
+ DownloadInfo *info = DownloadInfo::createFromMeta(fileName, m_ShowHidden);
+ if (info != NULL) {
+ m_ActiveDownloads.push_front(info);
+ }
}
- }
- if (m_ActiveDownloads.size() != downloadsBefore) {
- qDebug("downloads after refresh: %d", m_ActiveDownloads.size());
+ if (m_ActiveDownloads.size() != downloadsBefore) {
+ qDebug("downloads after refresh: %d", m_ActiveDownloads.size());
+ }
+ emit update(-1);
+ } catch (const std::bad_alloc&) {
+ reportError(tr("Memory allocation error (in refreshing directory)."));
}
- emit update(-1);
}
bool DownloadManager::addDownload(const QStringList &URLs,
- int modID, int fileID, const NexusInfo &nexusInfo)
+ int modID, int fileID, const ModRepositoryFileInfo *fileInfo)
{
QString fileName = QFileInfo(URLs.first()).fileName();
if (fileName.isEmpty()) {
@@ -316,20 +332,34 @@ bool DownloadManager::addDownload(const QStringList &URLs,
}
QNetworkRequest request(URLs.first());
- return addDownload(m_NexusInterface->getAccessManager()->get(request), URLs, fileName, modID, fileID, nexusInfo);
+ return addDownload(m_NexusInterface->getAccessManager()->get(request), URLs, fileName, modID, fileID, fileInfo);
+}
+
+
+bool DownloadManager::addDownload(QNetworkReply *reply, const ModRepositoryFileInfo *fileInfo)
+{
+ QString fileName = getFileNameFromNetworkReply(reply);
+ if (fileName.isEmpty()) {
+ fileName = "unknown";
+ }
+
+ return addDownload(reply, QStringList(reply->url().toString()), fileName, fileInfo->modID, fileInfo->fileID, fileInfo);
}
bool DownloadManager::addDownload(QNetworkReply *reply, const QStringList &URLs, const QString &fileName,
- int modID, int fileID, const NexusInfo &nexusInfo)
+ int modID, int fileID, const ModRepositoryFileInfo *fileInfo)
{
+ if (!reply->isRunning()) {
+ qDebug("this is not a running download! %d", reply->isFinished());
+ }
// download invoked from an already open network reply (i.e. download link in the browser)
- DownloadInfo *newDownload = DownloadInfo::createNew(nexusInfo, modID, fileID, URLs);
+ DownloadInfo *newDownload = DownloadInfo::createNew(fileInfo, URLs);
QString baseName = fileName;
- if (!nexusInfo.m_FileName.isEmpty()) {
- baseName = nexusInfo.m_FileName;
+ if (!fileInfo->fileName.isEmpty()) {
+ baseName = fileInfo->fileName;
} else {
QString dispoName = getFileNameFromNetworkReply(reply);
@@ -383,6 +413,7 @@ void DownloadManager::startDownload(QNetworkReply *reply, DownloadInfo *newDownl
}
newDownload->m_StartTime.start();
+ createMetaFile(newDownload);
if (!newDownload->m_Output.open(mode)) {
reportError(tr("failed to download %1: could not open output file: %2")
@@ -392,20 +423,24 @@ void DownloadManager::startDownload(QNetworkReply *reply, DownloadInfo *newDownl
connect(newDownload->m_Reply, SIGNAL(downloadProgress(qint64, qint64)), this, SLOT(downloadProgress(qint64, qint64)));
connect(newDownload->m_Reply, SIGNAL(finished()), this, SLOT(downloadFinished()));
+ connect(newDownload->m_Reply, SIGNAL(error(QNetworkReply::NetworkError)), this, SLOT(downloadError(QNetworkReply::NetworkError)));
connect(newDownload->m_Reply, SIGNAL(readyRead()), this, SLOT(downloadReadyRead()));
connect(newDownload->m_Reply, SIGNAL(metaDataChanged()), this, SLOT(metaDataChanged()));
if (!resume) {
newDownload->m_PreResumeSize = newDownload->m_Output.size();
-
- removePending(newDownload->m_ModID, newDownload->m_FileID);
+ removePending(newDownload->m_FileInfo->modID, newDownload->m_FileInfo->fileID);
emit aboutToUpdate();
-
m_ActiveDownloads.append(newDownload);
emit update(-1);
emit downloadAdded();
+
+ if (reply->isFinished()) {
+ // it's possible the download has already finished before this function ran
+ downloadFinished();
+ }
}
}
@@ -424,12 +459,11 @@ void DownloadManager::addNXMDownload(const QString &url)
}
emit aboutToUpdate();
-
m_PendingDownloads.append(std::make_pair(nxmInfo.modId(), nxmInfo.fileId()));
emit update(-1);
emit downloadAdded();
- m_RequestIDs.insert(m_NexusInterface->requestFileInfo(nxmInfo.modId(), nxmInfo.fileId(), this, nxmInfo.fileId()));
+ m_RequestIDs.insert(m_NexusInterface->requestFileInfo(nxmInfo.modId(), nxmInfo.fileId(), this, nxmInfo.fileId(), ""));
}
@@ -574,8 +608,11 @@ void DownloadManager::pauseDownload(int index)
DownloadInfo *info = m_ActiveDownloads.at(index);
if (info->m_State == STATE_DOWNLOADING) {
- setState(info, STATE_PAUSING);
- qDebug("pausing %d - %s", index, info->m_FileName.toUtf8().constData());
+ if (info->m_Reply->isRunning()) {
+ setState(info, STATE_PAUSING);
+ } else {
+ setState(info, STATE_PAUSED);
+ }
} else if ((info->m_State == STATE_FETCHINGMODINFO) || (info->m_State == STATE_FETCHINGFILEINFO)) {
setState(info, STATE_READY);
}
@@ -600,6 +637,11 @@ void DownloadManager::resumeDownloadInt(int index)
}
DownloadInfo *info = m_ActiveDownloads[index];
if (info->isPausedState()) {
+ if ((info->m_Urls.size() == 0)
+ || ((info->m_Urls.size() == 1) && (info->m_Urls[0].size() == 0))) {
+ emit showMessage(tr("No known download urls. Sorry, this download can't be resumed."));
+ return;
+ }
if (info->m_State == STATE_ERROR) {
info->m_CurrentUrl = (info->m_CurrentUrl + 1) % info->m_Urls.count();
}
@@ -635,16 +677,21 @@ void DownloadManager::queryInfo(int index)
}
DownloadInfo *info = m_ActiveDownloads[index];
+ if (info->m_FileInfo->repository != "Nexus") {
+ qWarning("re-querying file info is currently only possible with Nexus");
+ return;
+ }
+
if (info->m_State < DownloadManager::STATE_READY) {
// UI shouldn't allow this
return;
}
- if (info->m_ModID == 0UL) {
+ if (info->m_FileInfo->modID == 0UL) {
QString fileName = getFileName(index);
QString ignore;
- NexusInterface::interpretNexusFileName(fileName, ignore, info->m_ModID, true);
- if (info->m_ModID < 0) {
+ NexusInterface::interpretNexusFileName(fileName, ignore, info->m_FileInfo->modID, true);
+ if (info->m_FileInfo->modID < 0) {
QString modIDString;
while (modIDString.isEmpty()) {
modIDString = QInputDialog::getText(NULL, tr("Please enter the nexus mod id"), tr("Mod ID:"), QLineEdit::Normal,
@@ -657,12 +704,11 @@ void DownloadManager::queryInfo(int index)
modIDString.clear();
}
}
- info->m_ModID = modIDString.toInt(NULL, 10);
+ info->m_FileInfo->modID = modIDString.toInt(NULL, 10);
}
}
info->m_ReQueried = true;
setState(info, STATE_FETCHINGMODINFO);
-// m_RequestIDs.insert(m_NexusInterface->requestFiles(info->m_ModID, this, qVariantFromValue(static_cast<void*>(info))));
}
@@ -694,6 +740,34 @@ QString DownloadManager::getFilePath(int index) const
return m_OutputDirectory + "/" + m_ActiveDownloads.at(index)->m_FileName;
}
+QString DownloadManager::getFileTypeString(int fileType)
+{
+ switch (fileType) {
+ case 1: return tr("Main");
+ case 2: return tr("Update");
+ case 3: return tr("Optional");
+ case 4: return tr("Old");
+ case 5: return tr("Misc");
+ default: return tr("Unknown");
+ }
+}
+
+QString DownloadManager::getDisplayName(int index) const
+{
+ if ((index < 0) || (index >= m_ActiveDownloads.size())) {
+ throw MyException(tr("invalid index"));
+ }
+
+ DownloadInfo *info = m_ActiveDownloads.at(index);
+
+ if (!info->m_FileInfo->name.isEmpty()) {
+ return QString("%1 (%2, v%3)").arg(info->m_FileInfo->name)
+ .arg(getFileTypeString(info->m_FileInfo->fileCategory))
+ .arg(info->m_FileInfo->version.displayString());
+ } else {
+ return info->m_FileName;
+ }
+}
QString DownloadManager::getFileName(int index) const
{
@@ -755,7 +829,11 @@ bool DownloadManager::isInfoIncomplete(int index) const
}
DownloadInfo *info = m_ActiveDownloads.at(index);
- return (info->m_FileID == 0) || (info->m_ModID == 0) || info->m_NexusInfo.m_Version.isEmpty();
+ if (info->m_FileInfo->repository != "Nexus") {
+ // other repositories currently don't support re-querying info anyway
+ return false;
+ }
+ return (info->m_FileInfo->fileID == 0) || (info->m_FileInfo->modID == 0) || !info->m_FileInfo->version.isValid();
}
@@ -764,7 +842,7 @@ int DownloadManager::getModID(int index) const
if ((index < 0) || (index >= m_ActiveDownloads.size())) {
throw MyException(tr("invalid index"));
}
- return m_ActiveDownloads.at(index)->m_ModID;
+ return m_ActiveDownloads.at(index)->m_FileInfo->modID;
}
bool DownloadManager::isHidden(int index) const
@@ -776,13 +854,13 @@ bool DownloadManager::isHidden(int index) const
}
-NexusInfo DownloadManager::getNexusInfo(int index) const
+const ModRepositoryFileInfo *DownloadManager::getFileInfo(int index) const
{
if ((index < 0) || (index >= m_ActiveDownloads.size())) {
throw MyException(tr("invalid index"));
}
- return m_ActiveDownloads.at(index)->m_NexusInfo;
+ return m_ActiveDownloads.at(index)->m_FileInfo;
}
@@ -864,10 +942,10 @@ void DownloadManager::setState(DownloadManager::DownloadInfo *info, DownloadMana
info->m_Reply->abort();
} break;
case STATE_FETCHINGMODINFO: {
- m_RequestIDs.insert(m_NexusInterface->requestDescription(info->m_ModID, this, info->m_DownloadID));
+ m_RequestIDs.insert(m_NexusInterface->requestDescription(info->m_FileInfo->modID, this, info->m_DownloadID, QString()));
} break;
case STATE_FETCHINGFILEINFO: {
- m_RequestIDs.insert(m_NexusInterface->requestFiles(info->m_ModID, this, info->m_DownloadID));
+ m_RequestIDs.insert(m_NexusInterface->requestFiles(info->m_FileInfo->modID, this, info->m_DownloadID, QString()));
} break;
case STATE_READY: {
createMetaFile(info);
@@ -900,32 +978,40 @@ void DownloadManager::downloadProgress(qint64 bytesReceived, qint64 bytesTotal)
return;
}
int index = 0;
- DownloadInfo *info = findDownload(this->sender(), &index);
- if (info != NULL) {
- if (info->m_State == STATE_CANCELING) {
- setState(info, STATE_CANCELED);
- } else if (info->m_State == STATE_PAUSING) {
- setState(info, STATE_PAUSED);
- } else {
- if (bytesTotal > info->m_TotalSize) {
- info->m_TotalSize = bytesTotal;
- }
- int oldProgress = info->m_Progress;
- info->m_Progress = ((info->m_ResumePos + bytesReceived) * 100) / (info->m_ResumePos + bytesTotal);
- TaskProgressManager::instance().updateProgress(info->m_TaskProgressId, bytesReceived, bytesTotal);
- if (oldProgress != info->m_Progress) {
- emit update(index);
+ try {
+ DownloadInfo *info = findDownload(this->sender(), &index);
+ if (info != NULL) {
+ if (info->m_State == STATE_CANCELING) {
+ setState(info, STATE_CANCELED);
+ } else if (info->m_State == STATE_PAUSING) {
+ setState(info, STATE_PAUSED);
+ } else {
+ if (bytesTotal > info->m_TotalSize) {
+ info->m_TotalSize = bytesTotal;
+ }
+ int oldProgress = info->m_Progress;
+ info->m_Progress = ((info->m_ResumePos + bytesReceived) * 100) / (info->m_ResumePos + bytesTotal);
+ TaskProgressManager::instance().updateProgress(info->m_TaskProgressId, bytesReceived, bytesTotal);
+ if (oldProgress != info->m_Progress) {
+ emit update(index);
+ }
}
}
+ } catch (const std::bad_alloc&) {
+ reportError(tr("Memory allocation error (in processing progress event)."));
}
}
void DownloadManager::downloadReadyRead()
{
- DownloadInfo *info = findDownload(this->sender());
- if (info != NULL) {
- info->m_Output.write(info->m_Reply->readAll());
+ try {
+ DownloadInfo *info = findDownload(this->sender());
+ if (info != NULL) {
+ info->m_Output.write(info->m_Reply->readAll());
+ }
+ } catch (const std::bad_alloc&) {
+ reportError(tr("Memory allocation error (in processing downloaded data)."));
}
}
@@ -933,16 +1019,19 @@ void DownloadManager::downloadReadyRead()
void DownloadManager::createMetaFile(DownloadInfo *info)
{
QSettings metaFile(QString("%1.meta").arg(info->m_Output.fileName()), QSettings::IniFormat);
- metaFile.setValue("modID", info->m_ModID);
- metaFile.setValue("fileID", info->m_FileID);
+ metaFile.setValue("modID", info->m_FileInfo->modID);
+ metaFile.setValue("fileID", info->m_FileInfo->fileID);
metaFile.setValue("url", info->m_Urls.join(";"));
- metaFile.setValue("name", info->m_NexusInfo.m_Name);
- metaFile.setValue("modName", info->m_NexusInfo.m_ModName);
- metaFile.setValue("version", info->m_NexusInfo.m_Version);
- metaFile.setValue("fileTime", info->m_NexusInfo.m_FileTime);
- metaFile.setValue("fileCategory", info->m_NexusInfo.m_FileCategory);
- metaFile.setValue("newestVersion", info->m_NexusInfo.m_NewestVersion);
- metaFile.setValue("category", info->m_NexusInfo.m_Category);
+ metaFile.setValue("name", info->m_FileInfo->name);
+ metaFile.setValue("description", info->m_FileInfo->description);
+ metaFile.setValue("modName", info->m_FileInfo->modName);
+ metaFile.setValue("version", info->m_FileInfo->version.canonicalString());
+ metaFile.setValue("newestVersion", info->m_FileInfo->newestVersion.canonicalString());
+ metaFile.setValue("fileTime", info->m_FileInfo->fileTime);
+ metaFile.setValue("fileCategory", info->m_FileInfo->fileCategory);
+ metaFile.setValue("category", info->m_FileInfo->categoryID);
+ metaFile.setValue("repository", info->m_FileInfo->repository);
+ metaFile.setValue("userData", info->m_FileInfo->userData);
metaFile.setValue("installed", info->m_State == DownloadManager::STATE_INSTALLED);
metaFile.setValue("uninstalled", info->m_State == DownloadManager::STATE_UNINSTALLED);
metaFile.setValue("paused", (info->m_State == DownloadManager::STATE_PAUSED) ||
@@ -971,10 +1060,10 @@ void DownloadManager::nxmDescriptionAvailable(int, QVariant userData, QVariant r
DownloadInfo *info = downloadInfoByID(userData.toInt());
if (info == NULL) return;
- info->m_NexusInfo.m_Category = result["category_id"].toInt();
- info->m_NexusInfo.m_ModName = result["name"].toString().trimmed();
- info->m_NexusInfo.m_NewestVersion = result["version"].toString();
- if (info->m_FileID != 0) {
+ info->m_FileInfo->categoryID = result["category_id"].toInt();
+ info->m_FileInfo->modName = result["name"].toString().trimmed();
+ info->m_FileInfo->newestVersion.parse(result["version"].toString());
+ if (info->m_FileInfo->fileID != 0) {
setState(info, STATE_READY);
} else {
setState(info, STATE_FETCHINGFILEINFO);
@@ -993,6 +1082,18 @@ QDateTime DownloadManager::matchDate(const QString &timeString)
}
+EFileCategory convertFileCategory(int id)
+{
+ // TODO: need to handle file categories in the mod page plugin
+ switch (id) {
+ case 0: return TYPE_MAIN;
+ case 1: return TYPE_UPDATE;
+ case 2: return TYPE_OPTION;
+ default: return TYPE_MAIN;
+ }
+}
+
+
void DownloadManager::nxmFilesAvailable(int, QVariant userData, QVariant resultData, int requestID)
{
std::set<int>::iterator idIter = m_RequestIDs.find(requestID);
@@ -1024,14 +1125,14 @@ void DownloadManager::nxmFilesAvailable(int, QVariant userData, QVariant resultD
QString fileNameVariant = fileName.mid(0).replace(' ', '_');
if ((fileName == info->m_FileName) || (fileName == alternativeLocalName) ||
(fileNameVariant == info->m_FileName) || (fileNameVariant == alternativeLocalName)) {
- info->m_NexusInfo.m_Name = fileInfo["name"].toString();
- info->m_NexusInfo.m_Version = fileInfo["version"].toString();
- if (info->m_NexusInfo.m_Version.isEmpty()) {
- info->m_NexusInfo.m_Version = info->m_NexusInfo.m_NewestVersion;
+ info->m_FileInfo->name = fileInfo["name"].toString();
+ info->m_FileInfo->version.parse(fileInfo["version"].toString());
+ if (!info->m_FileInfo->version.isValid()) {
+ info->m_FileInfo->version = info->m_FileInfo->newestVersion;
}
- info->m_NexusInfo.m_FileCategory = fileInfo["category_id"].toInt();
- info->m_NexusInfo.m_FileTime = matchDate(fileInfo["date"].toString());
- info->m_FileID = fileInfo["id"].toInt();
+ info->m_FileInfo->fileCategory = convertFileCategory(fileInfo["category_id"].toInt());
+ info->m_FileInfo->fileTime = matchDate(fileInfo["date"].toString());
+ info->m_FileInfo->fileID = fileInfo["id"].toInt();
found = true;
break;
}
@@ -1050,16 +1151,16 @@ void DownloadManager::nxmFilesAvailable(int, QVariant userData, QVariant resultD
}
if (selection.exec() == QDialog::Accepted) {
QVariantMap fileInfo = selection.getChoiceData().toMap();
- info->m_NexusInfo.m_Name = fileInfo["name"].toString();
- info->m_NexusInfo.m_Version = fileInfo["version"].toString();
- info->m_NexusInfo.m_FileCategory = fileInfo["category_id"].toInt();
- info->m_FileID = fileInfo["id"].toInt();
+ info->m_FileInfo->name = fileInfo["name"].toString();
+ info->m_FileInfo->version.parse(fileInfo["version"].toString());
+ info->m_FileInfo->fileCategory = convertFileCategory(fileInfo["category_id"].toInt());
+ info->m_FileInfo->fileID = fileInfo["id"].toInt();
} else {
emit showMessage(tr("No matching file found on Nexus! Maybe this file is no longer available or it was renamed?"));
}
}
} else {
- if (info->m_FileID == 0) {
+ if (info->m_FileInfo->fileID == 0) {
qWarning("could not determine file id for %s (state %d)",
info->m_FileName.toUtf8().constData(), info->m_State);
}
@@ -1078,19 +1179,26 @@ void DownloadManager::nxmFileInfoAvailable(int modID, int fileID, QVariant userD
m_RequestIDs.erase(idIter);
}
- NexusInfo info;
+ ModRepositoryFileInfo *info = new ModRepositoryFileInfo();
QVariantMap result = resultData.toMap();
- info.m_Name = result["name"].toString();
- qDebug("file info received for %s", qPrintable(info.m_Name));
- info.m_Version = result["version"].toString();
- if (info.m_Version.isEmpty()) {
- info.m_Version = info.m_NewestVersion;
+ info->name = result["name"].toString();
+ qDebug("file info received for %s", qPrintable(info->name));
+ info->version.parse(result["version"].toString());
+ if (!info->version.isValid()) {
+ info->version = info->newestVersion;
}
- info.m_FileName = result["uri"].toString();
- info.m_FileTime = matchDate(result["date"].toString());
+ info->fileName = result["uri"].toString();
+ info->fileCategory = result["category_id"].toInt();
+ info->fileTime = matchDate(result["date"].toString());
+ info->description = BBCode::convertToHTML(result["description"].toString());
+
+ info->repository = "Nexus";
+ info->modID = modID;
+ info->fileID = fileID;
- m_RequestIDs.insert(m_NexusInterface->requestDownloadURL(modID, fileID, this, QVariant::fromValue(info)));
+ QObject *test = info;
+ m_RequestIDs.insert(m_NexusInterface->requestDownloadURL(modID, fileID, this, qVariantFromValue(test), QString()));
}
@@ -1138,7 +1246,7 @@ bool DownloadManager::ServerByPreference(const std::map<QString, int> &preferred
int DownloadManager::startDownloadURLs(const QStringList &urls)
{
- addDownload(urls, -1);
+ addDownload(urls, -1, -1, nullptr);
return m_ActiveDownloads.size() - 1;
}
@@ -1173,7 +1281,7 @@ void DownloadManager::nxmDownloadURLsAvailable(int modID, int fileID, QVariant u
m_RequestIDs.erase(idIter);
}
- NexusInfo info = userData.value<NexusInfo>();
+ ModRepositoryFileInfo *info = qobject_cast<ModRepositoryFileInfo*>(qvariant_cast<QObject*>(userData));
QVariantList resultList = resultData.toList();
if (resultList.length() == 0) {
removePending(modID, fileID);
@@ -1183,14 +1291,13 @@ void DownloadManager::nxmDownloadURLsAvailable(int modID, int fileID, QVariant u
std::sort(resultList.begin(), resultList.end(), boost::bind(&DownloadManager::ServerByPreference, m_PreferredServers, _1, _2));
- info.m_DownloadMap = resultList;
+ info->userData["downloadMap"] = resultList;
QStringList URLs;
foreach (const QVariant &server, resultList) {
URLs.append(server.toMap()["URI"].toString());
}
-
addDownload(URLs, modID, fileID, info);
}
@@ -1208,7 +1315,7 @@ void DownloadManager::nxmRequestFailed(int modID, int fileID, QVariant userData,
for (QVector<DownloadInfo*>::iterator iter = m_ActiveDownloads.begin(); iter != m_ActiveDownloads.end(); ++iter, ++index) {
DownloadInfo *info = *iter;
- if (info->m_ModID == modID) {
+ if (info->m_FileInfo->modID == modID) {
if (info->m_State < STATE_FETCHINGMODINFO) {
m_ActiveDownloads.erase(iter);
delete info;
@@ -1246,7 +1353,7 @@ void DownloadManager::downloadFinished()
textData) {
if (info->m_Tries == 0) {
if (textData && (reply->error() == QNetworkReply::NoError)) {
- emit showMessage(tr("Download failed. Server reported: %1").arg(readFileText(info->m_Output.fileName())));
+ emit showMessage(tr("Download failed. Server reported: %1").arg(QString(data)));
} else {
emit showMessage(tr("Download failed: %1 (%2)").arg(reply->errorString()).arg(reply->error()));
}
@@ -1279,20 +1386,27 @@ void DownloadManager::downloadFinished()
createMetaFile(info);
emit update(index);
} else {
-
QString url = info->m_Urls[info->m_CurrentUrl];
- foreach (const QVariant &server, info->m_NexusInfo.m_DownloadMap) {
- QVariantMap serverMap = server.toMap();
- if (serverMap["URI"].toString() == url) {
- int deltaTime = info->m_StartTime.secsTo(QTime::currentTime());
- if (deltaTime > 5) {
- emit downloadSpeed(serverMap["Name"].toString(), (info->m_TotalSize - info->m_PreResumeSize) / deltaTime);
- } // no division by zero please! Also, if the download is shorter than a few seconds, the result is way to inprecise
- break;
+ if (info->m_FileInfo->userData.contains("downloadMap")) {
+ foreach (const QVariant &server, info->m_FileInfo->userData["downloadMap"].toList()) {
+ QVariantMap serverMap = server.toMap();
+ if (serverMap["URI"].toString() == url) {
+ int deltaTime = info->m_StartTime.secsTo(QTime::currentTime());
+ if (deltaTime > 5) {
+ emit downloadSpeed(serverMap["Name"].toString(), (info->m_TotalSize - info->m_PreResumeSize) / deltaTime);
+ } // no division by zero please! Also, if the download is shorter than a few seconds, the result is way to inprecise
+ break;
+ }
}
}
- setState(info, STATE_FETCHINGMODINFO); // need to set this state before changing the file name, otherwise .unfinished is appended
+ bool isNexus = info->m_FileInfo->repository == "Nexus";
+ // need to change state before changing the file name, otherwise .unfinished is appended
+ if (isNexus) {
+ setState(info, STATE_FETCHINGMODINFO);
+ } else {
+ setState(info, STATE_NOFETCH);
+ }
QString newName = getFileNameFromNetworkReply(reply);
QString oldName = QFileInfo(info->m_Output).fileName();
@@ -1302,6 +1416,10 @@ void DownloadManager::downloadFinished()
info->setName(m_OutputDirectory + "/" + info->m_FileName, true); // don't rename but remove the ".unfinished" extension
}
+ if (!isNexus) {
+ setState(info, STATE_READY);
+ }
+
emit update(index);
}
reply->close();
@@ -1317,6 +1435,14 @@ void DownloadManager::downloadFinished()
}
+void DownloadManager::downloadError(QNetworkReply::NetworkError error)
+{
+ if (error != QNetworkReply::OperationCanceledError) {
+ qWarning("Download error occured: %d", error);
+ }
+}
+
+
void DownloadManager::metaDataChanged()
{
int index = 0;
@@ -1327,7 +1453,7 @@ void DownloadManager::metaDataChanged()
if (!newName.isEmpty() && (newName != info->m_FileName)) {
info->setName(getDownloadFileName(newName), true);
refreshAlphabeticalTranslation();
- if (!info->m_Output.open(QIODevice::WriteOnly | QIODevice::Append)) {
+ if (!info->m_Output.isOpen() && !info->m_Output.open(QIODevice::WriteOnly | QIODevice::Append)) {
reportError(tr("failed to re-open %1").arg(info->m_FileName));
setState(info, STATE_CANCELING);
}