From cb5cfe724208beb7d506868fc4e50d9f13e28a53 Mon Sep 17 00:00:00 2001 From: Petr Mrázek Date: Tue, 25 Feb 2014 00:51:24 +0100 Subject: Reorganize all the screenshot files --- CMakeLists.txt | 15 +++-- gui/dialogs/ScreenshotDialog.cpp | 16 ++--- gui/dialogs/ScreenshotDialog.h | 6 +- logic/lists/ScreenshotList.cpp | 112 ------------------------------- logic/lists/ScreenshotList.h | 77 --------------------- logic/net/ImgurAlbumCreation.cpp | 90 ------------------------- logic/net/ImgurAlbumCreation.h | 42 ------------ logic/net/ImgurUpload.cpp | 106 ----------------------------- logic/net/ImgurUpload.h | 30 --------- logic/screenshots/ImgurAlbumCreation.cpp | 90 +++++++++++++++++++++++++ logic/screenshots/ImgurAlbumCreation.h | 42 ++++++++++++ logic/screenshots/ImgurUpload.cpp | 106 +++++++++++++++++++++++++++++ logic/screenshots/ImgurUpload.h | 30 +++++++++ logic/screenshots/Screenshot.h | 15 +++++ logic/screenshots/ScreenshotList.cpp | 112 +++++++++++++++++++++++++++++++ logic/screenshots/ScreenshotList.h | 70 +++++++++++++++++++ 16 files changed, 485 insertions(+), 474 deletions(-) delete mode 100644 logic/lists/ScreenshotList.cpp delete mode 100644 logic/lists/ScreenshotList.h delete mode 100644 logic/net/ImgurAlbumCreation.cpp delete mode 100644 logic/net/ImgurAlbumCreation.h delete mode 100644 logic/net/ImgurUpload.cpp delete mode 100644 logic/net/ImgurUpload.h create mode 100644 logic/screenshots/ImgurAlbumCreation.cpp create mode 100644 logic/screenshots/ImgurAlbumCreation.h create mode 100644 logic/screenshots/ImgurUpload.cpp create mode 100644 logic/screenshots/ImgurUpload.h create mode 100644 logic/screenshots/Screenshot.h create mode 100644 logic/screenshots/ScreenshotList.cpp create mode 100644 logic/screenshots/ScreenshotList.h diff --git a/CMakeLists.txt b/CMakeLists.txt index 12a673e3..da7b0e0b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -372,10 +372,6 @@ logic/net/HttpMetaCache.cpp logic/net/PasteUpload.h logic/net/PasteUpload.cpp logic/net/URLConstants.h -logic/net/ImgurUpload.h -logic/net/ImgurUpload.cpp -logic/net/ImgurAlbumCreation.h -logic/net/ImgurAlbumCreation.cpp # Yggdrasil login stuff logic/auth/AuthSession.h @@ -466,8 +462,15 @@ logic/lists/ForgeVersionList.h logic/lists/ForgeVersionList.cpp logic/lists/JavaVersionList.h logic/lists/JavaVersionList.cpp -logic/lists/ScreenshotList.h -logic/lists/ScreenshotList.cpp + +# the screenshots feature +logic/screenshots/Screenshot.h +logic/screenshots/ScreenshotList.h +logic/screenshots/ScreenshotList.cpp +logic/screenshots/ImgurUpload.h +logic/screenshots/ImgurUpload.cpp +logic/screenshots/ImgurAlbumCreation.h +logic/screenshots/ImgurAlbumCreation.cpp # Icons logic/icons/MMCIcon.h diff --git a/gui/dialogs/ScreenshotDialog.cpp b/gui/dialogs/ScreenshotDialog.cpp index 76f87283..a88c8dfd 100644 --- a/gui/dialogs/ScreenshotDialog.cpp +++ b/gui/dialogs/ScreenshotDialog.cpp @@ -7,8 +7,8 @@ #include "ProgressDialog.h" #include "CustomMessageBox.h" #include "logic/net/NetJob.h" -#include "logic/net/ImgurUpload.h" -#include "logic/net/ImgurAlbumCreation.h" +#include "logic/screenshots/ImgurUpload.h" +#include "logic/screenshots/ImgurAlbumCreation.h" #include "logic/tasks/SequentialTask.h" ScreenshotDialog::ScreenshotDialog(ScreenshotList *list, QWidget *parent) @@ -30,10 +30,10 @@ QString ScreenshotDialog::message() const .arg(m_imgurAlbum->id(), m_imgurAlbum->deleteHash()); } -QList ScreenshotDialog::selected() const +QList ScreenshotDialog::selected() const { - QList> list; - QList> first = m_list->screenshots(); + QList list; + QList first = m_list->screenshots(); for (QModelIndex index : ui->listView->selectionModel()->selectedRows()) { list.append(first.at(index.row())); @@ -51,14 +51,14 @@ void ScreenshotDialog::on_uploadBtn_clicked() } SequentialTask *task = new SequentialTask(this); NetJob *job = new NetJob("Screenshot Upload"); - for (std::shared_ptr shot : m_uploaded) + for (auto shot : m_uploaded) { job->addNetAction(ImgurUpload::make(shot)); } NetJob *albumTask = new NetJob("Imgur Album Creation"); albumTask->addNetAction(m_imgurAlbum = ImgurAlbumCreation::make(m_uploaded)); - task->addTask(std::shared_ptr(job)); - task->addTask(std::shared_ptr(albumTask)); + task->addTask(NetJobPtr(job)); + task->addTask(NetJobPtr(albumTask)); ProgressDialog prog(this); if (prog.exec(task) == QDialog::Accepted) { diff --git a/gui/dialogs/ScreenshotDialog.h b/gui/dialogs/ScreenshotDialog.h index ac95b4f0..29dd6765 100644 --- a/gui/dialogs/ScreenshotDialog.h +++ b/gui/dialogs/ScreenshotDialog.h @@ -1,7 +1,7 @@ #pragma once #include -#include "logic/lists/ScreenshotList.h" +#include "logic/screenshots/ScreenshotList.h" class ImgurAlbumCreation; @@ -24,7 +24,7 @@ public: }; QString message() const; - QList> selected() const; + QList selected() const; private slots: @@ -35,6 +35,6 @@ slots: private: Ui::ScreenshotDialog *ui; ScreenshotList *m_list; - QList> m_uploaded; + QList m_uploaded; std::shared_ptr m_imgurAlbum; }; diff --git a/logic/lists/ScreenshotList.cpp b/logic/lists/ScreenshotList.cpp deleted file mode 100644 index eda57a03..00000000 --- a/logic/lists/ScreenshotList.cpp +++ /dev/null @@ -1,112 +0,0 @@ -#include "ScreenshotList.h" -#include "gui/dialogs/ScreenshotDialog.h" - -#include -#include -#include -#include "gui/dialogs/ProgressDialog.h" -#include "gui/dialogs/CustomMessageBox.h" - -ScreenshotList::ScreenshotList(BaseInstance *instance, QObject *parent) - : QAbstractListModel(parent), m_instance(instance) -{ -} - -int ScreenshotList::rowCount(const QModelIndex &) const -{ - return m_screenshots.size(); -} - -QVariant ScreenshotList::data(const QModelIndex &index, int role) const -{ - if (index.row() >= m_screenshots.size() || index.row() < 0) - return QVariant(); - - switch (role) - { - case Qt::DecorationRole: - return QIcon(m_screenshots.at(index.row())->file); - case Qt::DisplayRole: - return m_screenshots.at(index.row())->timestamp.toString("yyyy-MM-dd HH:mm:ss"); - case Qt::ToolTipRole: - return m_screenshots.at(index.row())->timestamp.toString("yyyy-MM-dd HH:mm:ss"); - case Qt::TextAlignmentRole: - return (int)(Qt::AlignHCenter | Qt::AlignVCenter); - default: - return QVariant(); - } -} - -QVariant ScreenshotList::headerData(int section, Qt::Orientation orientation, int role) const -{ - return QVariant(); -} - -Qt::ItemFlags ScreenshotList::flags(const QModelIndex &index) const -{ - return Qt::ItemIsSelectable | Qt::ItemIsEnabled; -} - -Task *ScreenshotList::load() -{ - return new ScreenshotLoadTask(this); -} - -ScreenshotLoadTask::ScreenshotLoadTask(ScreenshotList *list) : m_list(list) -{ -} - -ScreenshotLoadTask::~ScreenshotLoadTask() -{ -} - -void ScreenshotLoadTask::executeTask() -{ - auto dir = QDir(m_list->instance()->minecraftRoot()); - if (!dir.cd("screenshots")) - { - emitFailed("Selected instance does not have any screenshots!"); - return; - } - dir.setNameFilters(QStringList() << "*.png"); - this->m_results = QList(); - for (auto file : dir.entryList()) - { - ScreenShot *shot = new ScreenShot(); - shot->timestamp = QDateTime::fromString(file, "yyyy-MM-dd_HH.mm.ss.png"); - shot->file = dir.absoluteFilePath(file); - m_results.append(shot); - } - m_list->loadShots(m_results); - emitSucceeded(); -} -void ScreenshotList::deleteSelected(ScreenshotDialog *dialog) -{ - auto screens = dialog->selected(); - if (screens.isEmpty()) - { - return; - } - beginResetModel(); - QList>::const_iterator it; - for (it = screens.cbegin(); it != screens.cend(); it++) - { - std::shared_ptr = *it; - if (!QFile(shot->file).remove()) - { - CustomMessageBox::selectable(dialog, tr("Error!"), - tr("Failed to delete screenshots!"), - QMessageBox::Warning)->exec(); - break; - } - } - ProgressDialog refresh(dialog); - Task *t = load(); - if (refresh.exec(t) != QDialog::Accepted) - { - CustomMessageBox::selectable(dialog, tr("Error!"), - tr("Unable to refresh list: %1").arg(t->failReason()), - QMessageBox::Warning)->exec(); - } - endResetModel(); -} diff --git a/logic/lists/ScreenshotList.h b/logic/lists/ScreenshotList.h deleted file mode 100644 index 8e512ace..00000000 --- a/logic/lists/ScreenshotList.h +++ /dev/null @@ -1,77 +0,0 @@ -#pragma once - -#include -#include "logic/BaseInstance.h" -#include "logic/tasks/Task.h" - -class ScreenShot -{ -public: - QDateTime timestamp; - QString file; - QString url; - QString imgurId; -}; - -class ScreenshotList : public QAbstractListModel -{ - Q_OBJECT -public: - ScreenshotList(BaseInstance *instance, QObject *parent = 0); - - QVariant data(const QModelIndex &index, int role) const; - QVariant headerData(int section, Qt::Orientation orientation, int role) const; - - int rowCount(const QModelIndex &parent) const; - - Qt::ItemFlags flags(const QModelIndex &index) const; - - Task *load(); - - void loadShots(QList shots) - { - m_screenshots = shots; - } - - QList screenshots() const - { - return m_screenshots; - } - - BaseInstance *instance() const - { - return m_instance; - } - - void deleteSelected(class ScreenshotDialog *dialog); - -signals: - -public -slots: - -private: - QList m_screenshots; - BaseInstance *m_instance; -}; - -class ScreenshotLoadTask : public Task -{ - Q_OBJECT - -public: - explicit ScreenshotLoadTask(ScreenshotList *list); - ~ScreenshotLoadTask(); - - QList screenShots() const - { - return m_results; - } - -protected: - virtual void executeTask(); - -private: - ScreenshotList *m_list; - QList m_results; -}; diff --git a/logic/net/ImgurAlbumCreation.cpp b/logic/net/ImgurAlbumCreation.cpp deleted file mode 100644 index 0d8c4dc1..00000000 --- a/logic/net/ImgurAlbumCreation.cpp +++ /dev/null @@ -1,90 +0,0 @@ -#include "ImgurAlbumCreation.h" - -#include -#include -#include -#include - -#include "logic/lists/ScreenshotList.h" -#include "URLConstants.h" -#include "MultiMC.h" -#include "logger/QsLog.h" - -ImgurAlbumCreation::ImgurAlbumCreation(QList screenshots) : NetAction(), m_screenshots(screenshots) -{ - m_url = URLConstants::IMGUR_BASE_URL + "album.json"; - m_status = Job_NotStarted; -} - -void ImgurAlbumCreation::start() -{ - m_status = Job_InProgress; - QNetworkRequest request(m_url); - request.setHeader(QNetworkRequest::UserAgentHeader, "MultiMC/5.0 (Uncached)"); - request.setHeader(QNetworkRequest::ContentTypeHeader, "application/x-www-form-urlencoded"); - request.setRawHeader("Authorization", "Client-ID 5b97b0713fba4a3"); - request.setRawHeader("Accept", "application/json"); - - QStringList ids; - for (auto shot : m_screenshots) - { - ids.append(shot->imgurId); - } - - const QByteArray data = "ids=" + ids.join(',').toUtf8() + "&title=Minecraft%20Screenshots&privacy=hidden"; - - auto worker = MMC->qnam(); - QNetworkReply *rep = worker->post(request, data); - - m_reply = std::shared_ptr(rep); - connect(rep, &QNetworkReply::uploadProgress, this, &ImgurAlbumCreation::downloadProgress); - connect(rep, &QNetworkReply::finished, this, &ImgurAlbumCreation::downloadFinished); - connect(rep, SIGNAL(error(QNetworkReply::NetworkError)), - SLOT(downloadError(QNetworkReply::NetworkError))); -} -void ImgurAlbumCreation::downloadError(QNetworkReply::NetworkError error) -{ - QLOG_DEBUG() << m_reply->errorString(); - m_status = Job_Failed; -} -void ImgurAlbumCreation::downloadFinished() -{ - if (m_status != Job_Failed) - { - QByteArray data = m_reply->readAll(); - m_reply.reset(); - QJsonParseError jsonError; - QJsonDocument doc = QJsonDocument::fromJson(data, &jsonError); - if (jsonError.error != QJsonParseError::NoError) - { - QLOG_DEBUG() << jsonError.errorString(); - emit failed(m_index_within_job); - return; - } - auto object = doc.object(); - if (!object.value("success").toBool()) - { - QLOG_DEBUG() << doc.toJson(); - emit failed(m_index_within_job); - return; - } - m_deleteHash = object.value("data").toObject().value("deletehash").toString(); - m_id = object.value("data").toObject().value("id").toString(); - m_status = Job_Finished; - emit succeeded(m_index_within_job); - return; - } - else - { - QLOG_DEBUG() << m_reply->readAll(); - m_reply.reset(); - emit failed(m_index_within_job); - return; - } -} -void ImgurAlbumCreation::downloadProgress(qint64 bytesReceived, qint64 bytesTotal) -{ - m_total_progress = bytesTotal; - m_progress = bytesReceived; - emit progress(m_index_within_job, bytesReceived, bytesTotal); -} diff --git a/logic/net/ImgurAlbumCreation.h b/logic/net/ImgurAlbumCreation.h deleted file mode 100644 index 7be255df..00000000 --- a/logic/net/ImgurAlbumCreation.h +++ /dev/null @@ -1,42 +0,0 @@ -#pragma once -#include "NetAction.h" - -class ScreenShot; -typedef std::shared_ptr ImgurAlbumCreationPtr; -class ImgurAlbumCreation : public NetAction -{ -public: - explicit ImgurAlbumCreation(QList screenshots); - static ImgurAlbumCreationPtr make(QList screenshots) - { - return ImgurAlbumCreationPtr(new ImgurAlbumCreation(screenshots)); - } - - QString deleteHash() const - { - return m_deleteHash; - } - QString id() const - { - return m_id; - } - -protected -slots: - virtual void downloadProgress(qint64 bytesReceived, qint64 bytesTotal); - virtual void downloadError(QNetworkReply::NetworkError error); - virtual void downloadFinished(); - virtual void downloadReadyRead() - { - } - -public -slots: - virtual void start(); - -private: - QList m_screenshots; - - QString m_deleteHash; - QString m_id; -}; diff --git a/logic/net/ImgurUpload.cpp b/logic/net/ImgurUpload.cpp deleted file mode 100644 index 4992ee65..00000000 --- a/logic/net/ImgurUpload.cpp +++ /dev/null @@ -1,106 +0,0 @@ -#include "ImgurUpload.h" - -#include -#include -#include -#include -#include -#include -#include - -#include "logic/lists/ScreenshotList.h" -#include "URLConstants.h" -#include "MultiMC.h" -#include "logger/QsLog.h" - -ImgurUpload::ImgurUpload(ScreenShot *shot) : NetAction(), m_shot(shot) -{ - m_url = URLConstants::IMGUR_BASE_URL + "upload.json"; - m_status = Job_NotStarted; -} - -void ImgurUpload::start() -{ - m_status = Job_InProgress; - QNetworkRequest request(m_url); - request.setHeader(QNetworkRequest::UserAgentHeader, "MultiMC/5.0 (Uncached)"); - request.setRawHeader("Authorization", "Client-ID 5b97b0713fba4a3"); - request.setRawHeader("Accept", "application/json"); - - QFile f(m_shot->file); - if (!f.open(QFile::ReadOnly)) - { - emit failed(m_index_within_job); - return; - } - - QHttpMultiPart *multipart = new QHttpMultiPart(QHttpMultiPart::FormDataType); - QHttpPart filePart; - filePart.setBody(f.readAll().toBase64()); - filePart.setHeader(QNetworkRequest::ContentTypeHeader, "image/png"); - filePart.setHeader(QNetworkRequest::ContentDispositionHeader, "form-data; name=\"image\""); - multipart->append(filePart); - QHttpPart typePart; - typePart.setHeader(QNetworkRequest::ContentDispositionHeader, "form-data; name=\"type\""); - typePart.setBody("base64"); - multipart->append(typePart); - QHttpPart namePart; - namePart.setHeader(QNetworkRequest::ContentDispositionHeader, "form-data; name=\"name\""); - namePart.setBody(m_shot->timestamp.toString(Qt::ISODate).toUtf8()); - multipart->append(namePart); - - auto worker = MMC->qnam(); - QNetworkReply *rep = worker->post(request, multipart); - - m_reply = std::shared_ptr(rep); - connect(rep, &QNetworkReply::uploadProgress, this, &ImgurUpload::downloadProgress); - connect(rep, &QNetworkReply::finished, this, &ImgurUpload::downloadFinished); - connect(rep, SIGNAL(error(QNetworkReply::NetworkError)), - SLOT(downloadError(QNetworkReply::NetworkError))); -} -void ImgurUpload::downloadError(QNetworkReply::NetworkError error) -{ - QLOG_DEBUG() << m_reply->errorString(); - m_status = Job_Failed; -} -void ImgurUpload::downloadFinished() -{ - if (m_status != Job_Failed) - { - QByteArray data = m_reply->readAll(); - m_reply.reset(); - QJsonParseError jsonError; - QJsonDocument doc = QJsonDocument::fromJson(data, &jsonError); - if (jsonError.error != QJsonParseError::NoError) - { - QLOG_DEBUG() << jsonError.errorString(); - emit failed(m_index_within_job); - return; - } - auto object = doc.object(); - if (!object.value("success").toBool()) - { - QLOG_DEBUG() << doc.toJson(); - emit failed(m_index_within_job); - return; - } - m_shot->imgurId = object.value("data").toObject().value("id").toString(); - m_shot->url = object.value("data").toObject().value("link").toString(); - m_status = Job_Finished; - emit succeeded(m_index_within_job); - return; - } - else - { - QLOG_DEBUG() << m_reply->readAll(); - m_reply.reset(); - emit failed(m_index_within_job); - return; - } -} -void ImgurUpload::downloadProgress(qint64 bytesReceived, qint64 bytesTotal) -{ - m_total_progress = bytesTotal; - m_progress = bytesReceived; - emit progress(m_index_within_job, bytesReceived, bytesTotal); -} diff --git a/logic/net/ImgurUpload.h b/logic/net/ImgurUpload.h deleted file mode 100644 index e5e79587..00000000 --- a/logic/net/ImgurUpload.h +++ /dev/null @@ -1,30 +0,0 @@ -#pragma once -#include "NetAction.h" - -class ScreenShot; -typedef std::shared_ptr ImgurUploadPtr; -class ImgurUpload : public NetAction -{ -public: - explicit ImgurUpload(ScreenShot *shot); - static ImgurUploadPtr make(ScreenShot *shot) - { - return ImgurUploadPtr(new ImgurUpload(shot)); - } - -protected -slots: - virtual void downloadProgress(qint64 bytesReceived, qint64 bytesTotal); - virtual void downloadError(QNetworkReply::NetworkError error); - virtual void downloadFinished(); - virtual void downloadReadyRead() - { - } - -public -slots: - virtual void start(); - -private: - ScreenShot *m_shot; -}; diff --git a/logic/screenshots/ImgurAlbumCreation.cpp b/logic/screenshots/ImgurAlbumCreation.cpp new file mode 100644 index 00000000..e473952e --- /dev/null +++ b/logic/screenshots/ImgurAlbumCreation.cpp @@ -0,0 +1,90 @@ +#include "ImgurAlbumCreation.h" + +#include +#include +#include +#include + +#include "logic/screenshots//ScreenshotList.h" +#include "logic/net/URLConstants.h" +#include "MultiMC.h" +#include "logger/QsLog.h" + +ImgurAlbumCreation::ImgurAlbumCreation(QList screenshots) : NetAction(), m_screenshots(screenshots) +{ + m_url = URLConstants::IMGUR_BASE_URL + "album.json"; + m_status = Job_NotStarted; +} + +void ImgurAlbumCreation::start() +{ + m_status = Job_InProgress; + QNetworkRequest request(m_url); + request.setHeader(QNetworkRequest::UserAgentHeader, "MultiMC/5.0 (Uncached)"); + request.setHeader(QNetworkRequest::ContentTypeHeader, "application/x-www-form-urlencoded"); + request.setRawHeader("Authorization", "Client-ID 5b97b0713fba4a3"); + request.setRawHeader("Accept", "application/json"); + + QStringList ids; + for (auto shot : m_screenshots) + { + ids.append(shot->imgurId); + } + + const QByteArray data = "ids=" + ids.join(',').toUtf8() + "&title=Minecraft%20Screenshots&privacy=hidden"; + + auto worker = MMC->qnam(); + QNetworkReply *rep = worker->post(request, data); + + m_reply = std::shared_ptr(rep); + connect(rep, &QNetworkReply::uploadProgress, this, &ImgurAlbumCreation::downloadProgress); + connect(rep, &QNetworkReply::finished, this, &ImgurAlbumCreation::downloadFinished); + connect(rep, SIGNAL(error(QNetworkReply::NetworkError)), + SLOT(downloadError(QNetworkReply::NetworkError))); +} +void ImgurAlbumCreation::downloadError(QNetworkReply::NetworkError error) +{ + QLOG_DEBUG() << m_reply->errorString(); + m_status = Job_Failed; +} +void ImgurAlbumCreation::downloadFinished() +{ + if (m_status != Job_Failed) + { + QByteArray data = m_reply->readAll(); + m_reply.reset(); + QJsonParseError jsonError; + QJsonDocument doc = QJsonDocument::fromJson(data, &jsonError); + if (jsonError.error != QJsonParseError::NoError) + { + QLOG_DEBUG() << jsonError.errorString(); + emit failed(m_index_within_job); + return; + } + auto object = doc.object(); + if (!object.value("success").toBool()) + { + QLOG_DEBUG() << doc.toJson(); + emit failed(m_index_within_job); + return; + } + m_deleteHash = object.value("data").toObject().value("deletehash").toString(); + m_id = object.value("data").toObject().value("id").toString(); + m_status = Job_Finished; + emit succeeded(m_index_within_job); + return; + } + else + { + QLOG_DEBUG() << m_reply->readAll(); + m_reply.reset(); + emit failed(m_index_within_job); + return; + } +} +void ImgurAlbumCreation::downloadProgress(qint64 bytesReceived, qint64 bytesTotal) +{ + m_total_progress = bytesTotal; + m_progress = bytesReceived; + emit progress(m_index_within_job, bytesReceived, bytesTotal); +} diff --git a/logic/screenshots/ImgurAlbumCreation.h b/logic/screenshots/ImgurAlbumCreation.h new file mode 100644 index 00000000..6e8fbe94 --- /dev/null +++ b/logic/screenshots/ImgurAlbumCreation.h @@ -0,0 +1,42 @@ +#pragma once +#include "logic/net/NetAction.h" +#include "Screenshot.h" + +typedef std::shared_ptr ImgurAlbumCreationPtr; +class ImgurAlbumCreation : public NetAction +{ +public: + explicit ImgurAlbumCreation(QList screenshots); + static ImgurAlbumCreationPtr make(QList screenshots) + { + return ImgurAlbumCreationPtr(new ImgurAlbumCreation(screenshots)); + } + + QString deleteHash() const + { + return m_deleteHash; + } + QString id() const + { + return m_id; + } + +protected +slots: + virtual void downloadProgress(qint64 bytesReceived, qint64 bytesTotal); + virtual void downloadError(QNetworkReply::NetworkError error); + virtual void downloadFinished(); + virtual void downloadReadyRead() + { + } + +public +slots: + virtual void start(); + +private: + QList m_screenshots; + + QString m_deleteHash; + QString m_id; +}; diff --git a/logic/screenshots/ImgurUpload.cpp b/logic/screenshots/ImgurUpload.cpp new file mode 100644 index 00000000..62033ef5 --- /dev/null +++ b/logic/screenshots/ImgurUpload.cpp @@ -0,0 +1,106 @@ +#include "ImgurUpload.h" + +#include +#include +#include +#include +#include +#include +#include + +#include "logic/screenshots/ScreenshotList.h" +#include "logic/net/URLConstants.h" +#include "MultiMC.h" +#include "logger/QsLog.h" + +ImgurUpload::ImgurUpload(ScreenshotPtr shot) : NetAction(), m_shot(shot) +{ + m_url = URLConstants::IMGUR_BASE_URL + "upload.json"; + m_status = Job_NotStarted; +} + +void ImgurUpload::start() +{ + m_status = Job_InProgress; + QNetworkRequest request(m_url); + request.setHeader(QNetworkRequest::UserAgentHeader, "MultiMC/5.0 (Uncached)"); + request.setRawHeader("Authorization", "Client-ID 5b97b0713fba4a3"); + request.setRawHeader("Accept", "application/json"); + + QFile f(m_shot->file); + if (!f.open(QFile::ReadOnly)) + { + emit failed(m_index_within_job); + return; + } + + QHttpMultiPart *multipart = new QHttpMultiPart(QHttpMultiPart::FormDataType); + QHttpPart filePart; + filePart.setBody(f.readAll().toBase64()); + filePart.setHeader(QNetworkRequest::ContentTypeHeader, "image/png"); + filePart.setHeader(QNetworkRequest::ContentDispositionHeader, "form-data; name=\"image\""); + multipart->append(filePart); + QHttpPart typePart; + typePart.setHeader(QNetworkRequest::ContentDispositionHeader, "form-data; name=\"type\""); + typePart.setBody("base64"); + multipart->append(typePart); + QHttpPart namePart; + namePart.setHeader(QNetworkRequest::ContentDispositionHeader, "form-data; name=\"name\""); + namePart.setBody(m_shot->timestamp.toString(Qt::ISODate).toUtf8()); + multipart->append(namePart); + + auto worker = MMC->qnam(); + QNetworkReply *rep = worker->post(request, multipart); + + m_reply = std::shared_ptr(rep); + connect(rep, &QNetworkReply::uploadProgress, this, &ImgurUpload::downloadProgress); + connect(rep, &QNetworkReply::finished, this, &ImgurUpload::downloadFinished); + connect(rep, SIGNAL(error(QNetworkReply::NetworkError)), + SLOT(downloadError(QNetworkReply::NetworkError))); +} +void ImgurUpload::downloadError(QNetworkReply::NetworkError error) +{ + QLOG_DEBUG() << m_reply->errorString(); + m_status = Job_Failed; +} +void ImgurUpload::downloadFinished() +{ + if (m_status != Job_Failed) + { + QByteArray data = m_reply->readAll(); + m_reply.reset(); + QJsonParseError jsonError; + QJsonDocument doc = QJsonDocument::fromJson(data, &jsonError); + if (jsonError.error != QJsonParseError::NoError) + { + QLOG_DEBUG() << jsonError.errorString(); + emit failed(m_index_within_job); + return; + } + auto object = doc.object(); + if (!object.value("success").toBool()) + { + QLOG_DEBUG() << doc.toJson(); + emit failed(m_index_within_job); + return; + } + m_shot->imgurId = object.value("data").toObject().value("id").toString(); + m_shot->url = object.value("data").toObject().value("link").toString(); + m_status = Job_Finished; + emit succeeded(m_index_within_job); + return; + } + else + { + QLOG_DEBUG() << m_reply->readAll(); + m_reply.reset(); + emit failed(m_index_within_job); + return; + } +} +void ImgurUpload::downloadProgress(qint64 bytesReceived, qint64 bytesTotal) +{ + m_total_progress = bytesTotal; + m_progress = bytesReceived; + emit progress(m_index_within_job, bytesReceived, bytesTotal); +} diff --git a/logic/screenshots/ImgurUpload.h b/logic/screenshots/ImgurUpload.h new file mode 100644 index 00000000..1111a8d0 --- /dev/null +++ b/logic/screenshots/ImgurUpload.h @@ -0,0 +1,30 @@ +#pragma once +#include "logic/net/NetAction.h" +#include "Screenshot.h" + +typedef std::shared_ptr ImgurUploadPtr; +class ImgurUpload : public NetAction +{ +public: + explicit ImgurUpload(ScreenshotPtr shot); + static ImgurUploadPtr make(ScreenshotPtr shot) + { + return ImgurUploadPtr(new ImgurUpload(shot)); + } + +protected +slots: + virtual void downloadProgress(qint64 bytesReceived, qint64 bytesTotal); + virtual void downloadError(QNetworkReply::NetworkError error); + virtual void downloadFinished(); + virtual void downloadReadyRead() + { + } + +public +slots: + virtual void start(); + +private: + ScreenshotPtr m_shot; +}; diff --git a/logic/screenshots/Screenshot.h b/logic/screenshots/Screenshot.h new file mode 100644 index 00000000..194e70e5 --- /dev/null +++ b/logic/screenshots/Screenshot.h @@ -0,0 +1,15 @@ +#pragma once + +#include +#include +#include + +struct ScreenShot +{ + QDateTime timestamp; + QString file; + QString url; + QString imgurId; +}; + +typedef std::shared_ptr ScreenshotPtr; diff --git a/logic/screenshots/ScreenshotList.cpp b/logic/screenshots/ScreenshotList.cpp new file mode 100644 index 00000000..def1bdf7 --- /dev/null +++ b/logic/screenshots/ScreenshotList.cpp @@ -0,0 +1,112 @@ +#include "ScreenshotList.h" +#include "gui/dialogs/ScreenshotDialog.h" + +#include +#include +#include +#include "gui/dialogs/ProgressDialog.h" +#include "gui/dialogs/CustomMessageBox.h" + +ScreenshotList::ScreenshotList(BaseInstance *instance, QObject *parent) + : QAbstractListModel(parent), m_instance(instance) +{ +} + +int ScreenshotList::rowCount(const QModelIndex &) const +{ + return m_screenshots.size(); +} + +QVariant ScreenshotList::data(const QModelIndex &index, int role) const +{ + if (index.row() >= m_screenshots.size() || index.row() < 0) + return QVariant(); + + switch (role) + { + case Qt::DecorationRole: + return QIcon(m_screenshots.at(index.row())->file); + case Qt::DisplayRole: + return m_screenshots.at(index.row())->timestamp.toString("yyyy-MM-dd HH:mm:ss"); + case Qt::ToolTipRole: + return m_screenshots.at(index.row())->timestamp.toString("yyyy-MM-dd HH:mm:ss"); + case Qt::TextAlignmentRole: + return (int)(Qt::AlignHCenter | Qt::AlignVCenter); + default: + return QVariant(); + } +} + +QVariant ScreenshotList::headerData(int section, Qt::Orientation orientation, int role) const +{ + return QVariant(); +} + +Qt::ItemFlags ScreenshotList::flags(const QModelIndex &index) const +{ + return Qt::ItemIsSelectable | Qt::ItemIsEnabled; +} + +Task *ScreenshotList::load() +{ + return new ScreenshotLoadTask(this); +} + +ScreenshotLoadTask::ScreenshotLoadTask(ScreenshotList *list) : m_list(list) +{ +} + +ScreenshotLoadTask::~ScreenshotLoadTask() +{ +} + +void ScreenshotLoadTask::executeTask() +{ + auto dir = QDir(m_list->instance()->minecraftRoot()); + if (!dir.cd("screenshots")) + { + emitFailed("Selected instance does not have any screenshots!"); + return; + } + dir.setNameFilters(QStringList() << "*.png"); + this->m_results.clear(); + for (auto file : dir.entryList()) + { + ScreenShot *shot = new ScreenShot(); + shot->timestamp = QDateTime::fromString(file, "yyyy-MM-dd_HH.mm.ss.png"); + shot->file = dir.absoluteFilePath(file); + m_results.append(ScreenshotPtr(shot)); + } + m_list->loadShots(m_results); + emitSucceeded(); +} +void ScreenshotList::deleteSelected(ScreenshotDialog *dialog) +{ + auto screens = dialog->selected(); + if (screens.isEmpty()) + { + return; + } + beginResetModel(); + QList>::const_iterator it; + for (it = screens.cbegin(); it != screens.cend(); it++) + { + auto shot = *it; + if (!QFile(shot->file).remove()) + { + CustomMessageBox::selectable(dialog, tr("Error!"), + tr("Failed to delete screenshots!"), + QMessageBox::Warning)->exec(); + break; + } + } + ProgressDialog refresh(dialog); + Task *t = load(); + if (refresh.exec(t) != QDialog::Accepted) + { + CustomMessageBox::selectable(dialog, tr("Error!"), + tr("Unable to refresh list: %1").arg(t->failReason()), + QMessageBox::Warning)->exec(); + } + endResetModel(); +} diff --git a/logic/screenshots/ScreenshotList.h b/logic/screenshots/ScreenshotList.h new file mode 100644 index 00000000..ca6314e9 --- /dev/null +++ b/logic/screenshots/ScreenshotList.h @@ -0,0 +1,70 @@ +#pragma once + +#include +#include "logic/BaseInstance.h" +#include "logic/tasks/Task.h" + +#include "Screenshot.h" + +class ScreenshotList : public QAbstractListModel +{ + Q_OBJECT +public: + ScreenshotList(BaseInstance *instance, QObject *parent = 0); + + QVariant data(const QModelIndex &index, int role) const; + QVariant headerData(int section, Qt::Orientation orientation, int role) const; + + int rowCount(const QModelIndex &parent) const; + + Qt::ItemFlags flags(const QModelIndex &index) const; + + Task *load(); + + void loadShots(QList shots) + { + m_screenshots = shots; + } + + QList screenshots() const + { + return m_screenshots; + } + + BaseInstance *instance() const + { + return m_instance; + } + + void deleteSelected(class ScreenshotDialog *dialog); + +signals: + +public +slots: + +private: + QList m_screenshots; + BaseInstance *m_instance; +}; + +class ScreenshotLoadTask : public Task +{ + Q_OBJECT + +public: + explicit ScreenshotLoadTask(ScreenshotList *list); + ~ScreenshotLoadTask(); + + QList screenShots() const + { + return m_results; + } + +protected: + virtual void executeTask(); + +private: + ScreenshotList *m_list; + QList m_results; +}; -- cgit