diff --git a/flameshot.pro b/flameshot.pro
index 84a2e65b..e48f4dd8 100644
--- a/flameshot.pro
+++ b/flameshot.pro
@@ -96,6 +96,7 @@ SOURCES += src/main.cpp \
src/tools/copy/copytool.cpp \
src/tools/exit/exittool.cpp \
src/tools/imgur/imguruploadertool.cpp \
+ src/tools/imgs3/imgs3uploadertool.cpp \
src/tools/line/linetool.cpp \
src/tools/marker/markertool.cpp \
src/tools/move/movetool.cpp \
@@ -113,6 +114,7 @@ SOURCES += src/main.cpp \
src/cli/commandargument.cpp \
src/utils/screenshotsaver.cpp \
src/tools/imgur/imguruploader.cpp \
+ src/tools/imgs3/imgs3uploader.cpp \
src/widgets/loadspinner.cpp \
src/widgets/imagelabel.cpp \
src/widgets/notificationwidget.cpp \
@@ -170,6 +172,7 @@ HEADERS += src/widgets/capture/buttonhandler.h \
src/tools/copy/copytool.h \
src/tools/exit/exittool.h \
src/tools/imgur/imguruploadertool.h \
+ src/tools/imgs3/imgs3uploadertool.h \
src/tools/line/linetool.h \
src/tools/marker/markertool.h \
src/tools/move/movetool.h \
@@ -186,6 +189,7 @@ HEADERS += src/widgets/capture/buttonhandler.h \
src/cli/commandargument.h \
src/utils/screenshotsaver.h \
src/tools/imgur/imguruploader.h \
+ src/tools/imgs3/imgs3uploader.h \
src/widgets/loadspinner.h \
src/widgets/imagelabel.h \
src/widgets/notificationwidget.h \
@@ -289,3 +293,5 @@ unix:!macx {
# Imgur API data
include(src/imgur.pri)
+# ImgS3 API data
+include(src/imgs3.pri)
diff --git a/src/imgs3.pri b/src/imgs3.pri
new file mode 100644
index 00000000..662abfde
--- /dev/null
+++ b/src/imgs3.pri
@@ -0,0 +1,7 @@
+# Use default ImgS3 client_id if user did not pass
+# this variable to qmake
+isEmpty(IMG_S3_CLIENT_ID) {
+ IMG_S3_CLIENT_ID = "313baf0c7b4d3f0"
+}
+
+DEFINES += IMG_S3_CLIENT_ID=\\\"$${IMG_S3_CLIENT_ID}\\\"
diff --git a/src/tools/imgs3/imgs3uploader.cpp b/src/tools/imgs3/imgs3uploader.cpp
new file mode 100644
index 00000000..ee8f7a09
--- /dev/null
+++ b/src/tools/imgs3/imgs3uploader.cpp
@@ -0,0 +1,274 @@
+// Copyright(c) 2017-2019 Alejandro Sirgo Rica & Contributors
+//
+// This file is part of Flameshot.
+//
+// Flameshot is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// Flameshot is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with Flameshot. If not, see .
+
+#include "imgs3uploader.h"
+#include "src/utils/filenamehandler.h"
+#include "src/utils/systemnotification.h"
+#include "src/widgets/loadspinner.h"
+#include "src/widgets/imagelabel.h"
+#include "src/widgets/notificationwidget.h"
+#include "src/utils/confighandler.h"
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+ImgS3Uploader::ImgS3Uploader(const QPixmap &capture, QWidget *parent) :
+ QWidget(parent), m_pixmap(capture)
+{
+ setWindowTitle(tr("Upload to ImgS3"));
+ setWindowIcon(QIcon(":img/app/flameshot.svg"));
+
+ m_spinner = new LoadSpinner(this);
+ m_spinner->setColor(ConfigHandler().uiMainColorValue());
+ m_spinner->start();
+
+ m_infoLabel = new QLabel(tr("Uploading Image"));
+
+ m_vLayout = new QVBoxLayout();
+ setLayout(m_vLayout);
+ m_vLayout->addWidget(m_spinner, 0, Qt::AlignHCenter);
+ m_vLayout->addWidget(m_infoLabel);
+
+ m_NetworkAM = new QNetworkAccessManager(this);
+ connect(m_NetworkAM, &QNetworkAccessManager::finished, this, &ImgS3Uploader::handleReply);
+
+ m_NetworkAMCreds = new QNetworkAccessManager(this);
+ connect(m_NetworkAMCreds, &QNetworkAccessManager::finished, this, &ImgS3Uploader::handleCredsReply);
+
+ setAttribute(Qt::WA_DeleteOnClose);
+
+ upload();
+}
+
+void ImgS3Uploader::handleReply(QNetworkReply *reply) {
+ m_spinner->deleteLater();
+ if (reply->error() == QNetworkReply::NoError) {
+ if (ConfigHandler().copyAndCloseAfterUploadEnabled()) {
+ QApplication::clipboard()->setText(m_imageURL.toString());
+ SystemNotification().sendMessage(QObject::tr("URL copied to clipboard."));
+ close();
+ } else {
+ onUploadOk();
+ }
+ } else {
+ QString reason = reply->attribute( QNetworkRequest::HttpReasonPhraseAttribute ).toString();
+ qDebug() << reply->header(QNetworkRequest::ContentDispositionHeader);
+ qDebug() << reply->header(QNetworkRequest::ContentTypeHeader);
+ qDebug() << reply->readAll();
+ qDebug() << reason;
+ m_infoLabel->setText(reply->errorString());
+ }
+ new QShortcut(Qt::Key_Escape, this, SLOT(close()));
+}
+
+void ImgS3Uploader::startDrag() {
+ QMimeData *mimeData = new QMimeData;
+ mimeData->setUrls(QList { m_imageURL });
+ mimeData->setImageData(m_pixmap);
+
+ QDrag *dragHandler = new QDrag(this);
+ dragHandler->setMimeData(mimeData);
+ dragHandler->setPixmap(m_pixmap.scaled(256, 256, Qt::KeepAspectRatioByExpanding,
+ Qt::SmoothTransformation));
+ dragHandler->exec();
+}
+
+void ImgS3Uploader::handleCredsReply(QNetworkReply *reply){
+ if (reply->error() == QNetworkReply::NoError) {
+ QJsonDocument response = QJsonDocument::fromJson(reply->readAll());
+ uploadToS3(response);
+ } else {
+ m_infoLabel->setText(reply->errorString());
+ }
+ new QShortcut(Qt::Key_Escape, this, SLOT(close()));
+}
+
+void ImgS3Uploader::uploadToS3(QJsonDocument &response) {
+ QJsonObject json = response.object();
+ QJsonObject formData = json["formData"].toObject();
+ QJsonObject fields = formData["fields"].toObject();
+
+ QString resultURL = json["resultURL"].toString();
+
+ QString url = formData["url"].toString();
+
+ QString acl = fields["acl"].toString();
+ QString contentType = fields["Content-Type"].toString();
+ QString key = fields["Key"].toString();
+ QString bucket = fields["bucket"].toString();
+ QString xAmzAlgorithm = fields["X-Amz-Algorithm"].toString();
+ QString xAmzCredential = fields["X-Amz-Credential"].toString();
+ QString xAmzDate = fields["X-Amz-Date"].toString();
+ QString xAmzSecurityToken = fields["X-Amz-Security-Token"].toString();
+ QString policy = fields["Policy"].toString();
+ QString xAmzSignature = fields["X-Amz-Signature"].toString();
+
+ //
+ QHttpMultiPart *multiPart = new QHttpMultiPart(QHttpMultiPart::FormDataType);
+
+ QHttpPart aclPart;
+ aclPart.setHeader(QNetworkRequest::ContentDispositionHeader, QVariant("form-data; name=\"acl\""));
+ aclPart.setBody(acl.toLatin1());
+ multiPart->append(aclPart);
+
+ QHttpPart contentTypePart;
+ contentTypePart.setHeader(QNetworkRequest::ContentDispositionHeader, QVariant("form-data; name=\"Content-Type\""));
+ contentTypePart.setBody(contentType.toLatin1());
+ multiPart->append(contentTypePart);
+
+ QHttpPart keyPart;
+ keyPart.setHeader(QNetworkRequest::ContentDispositionHeader, QVariant("form-data; name=\"Key\""));
+ keyPart.setBody(key.toLatin1());
+ multiPart->append(keyPart);
+
+ QHttpPart bucketPart;
+ bucketPart.setHeader(QNetworkRequest::ContentDispositionHeader, QVariant("form-data; name=\"bucket\""));
+ bucketPart.setBody(bucket.toLatin1());
+ multiPart->append(bucketPart);
+
+ QHttpPart xAmzAlgorithmPart;
+ xAmzAlgorithmPart.setHeader(QNetworkRequest::ContentDispositionHeader, QVariant("form-data; name=\"X-Amz-Algorithm\""));
+ xAmzAlgorithmPart.setBody(xAmzAlgorithm.toLatin1());
+ multiPart->append(xAmzAlgorithmPart);
+
+ QHttpPart xAmzCredentialPart;
+ xAmzCredentialPart.setHeader(QNetworkRequest::ContentDispositionHeader, QVariant("form-data; name=\"X-Amz-Credential\""));
+ xAmzCredentialPart.setBody(xAmzCredential.toLatin1());
+ multiPart->append(xAmzCredentialPart);
+
+ QHttpPart xAmzDatePart;
+ xAmzDatePart.setHeader(QNetworkRequest::ContentDispositionHeader, QVariant("form-data; name=\"X-Amz-Date\""));
+ xAmzDatePart.setBody(xAmzDate.toLatin1());
+ multiPart->append(xAmzDatePart);
+
+ QHttpPart xAmzSecurityTokenPart;
+ xAmzSecurityTokenPart.setHeader(QNetworkRequest::ContentDispositionHeader, QVariant("form-data; name=\"X-Amz-Security-Token\""));
+ xAmzSecurityTokenPart.setBody(xAmzSecurityToken.toLatin1());
+ multiPart->append(xAmzSecurityTokenPart);
+
+ QHttpPart policyPart;
+ policyPart.setHeader(QNetworkRequest::ContentDispositionHeader, QVariant("form-data; name=\"Policy\""));
+ policyPart.setBody(policy.toLatin1());
+ multiPart->append(policyPart);
+
+ QHttpPart xAmzSignaturePart;
+ xAmzSignaturePart.setHeader(QNetworkRequest::ContentDispositionHeader, QVariant("form-data; name=\"X-Amz-Signature\""));
+ xAmzSignaturePart.setBody(xAmzSignature.toLatin1());
+ multiPart->append(xAmzSignaturePart);
+
+
+ QHttpPart imagePart;
+ imagePart.setHeader(QNetworkRequest::ContentTypeHeader, QVariant("image/png"));
+ imagePart.setHeader(QNetworkRequest::ContentDispositionHeader,
+ QVariant("form-data; name=\"file\""));
+
+ QByteArray byteArray;
+ QBuffer buffer(&byteArray);
+ buffer.open(QIODevice::WriteOnly);
+ m_pixmap.save(&buffer, "PNG");
+
+ imagePart.setBody(byteArray);
+ multiPart->append(imagePart);
+
+ m_imageURL.setUrl(resultURL);
+
+ QUrl qUrl(url);
+ QNetworkRequest request(qUrl);
+ m_NetworkAM->post(request, multiPart);
+}
+
+void ImgS3Uploader::upload() {
+ // get creads
+ QUrl creds("https://api.img.rnd.namecheap.net/");
+ QNetworkRequest requestCreds(creds);
+ m_NetworkAMCreds->get(requestCreds);
+}
+
+void ImgS3Uploader::onUploadOk() {
+ m_infoLabel->deleteLater();
+
+ m_notification = new NotificationWidget();
+ m_vLayout->addWidget(m_notification);
+
+ ImageLabel *imageLabel = new ImageLabel();
+ imageLabel->setScreenshot(m_pixmap);
+ imageLabel->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
+ connect(imageLabel, &ImageLabel::dragInitiated, this, &ImgS3Uploader::startDrag);
+ m_vLayout->addWidget(imageLabel);
+
+ m_hLayout = new QHBoxLayout();
+ m_vLayout->addLayout(m_hLayout);
+
+ m_copyUrlButton = new QPushButton(tr("Copy URL"));
+ m_openUrlButton = new QPushButton(tr("Open URL"));
+ m_openDeleteUrlButton = new QPushButton(tr("Delete image"));
+ m_toClipboardButton = new QPushButton(tr("Image to Clipboard."));
+ m_hLayout->addWidget(m_copyUrlButton);
+ m_hLayout->addWidget(m_openUrlButton);
+ m_hLayout->addWidget(m_openDeleteUrlButton);
+ m_hLayout->addWidget(m_toClipboardButton);
+
+ connect(m_copyUrlButton, &QPushButton::clicked,
+ this, &ImgS3Uploader::copyURL);
+ connect(m_openUrlButton, &QPushButton::clicked,
+ this, &ImgS3Uploader::openURL);
+ connect(m_openDeleteUrlButton, &QPushButton::clicked,
+ this, &ImgS3Uploader::openDeleteURL);
+ connect(m_toClipboardButton, &QPushButton::clicked,
+ this, &ImgS3Uploader::copyImage);
+}
+
+void ImgS3Uploader::openURL() {
+ bool successful = QDesktopServices::openUrl(m_imageURL);
+ if (!successful) {
+ m_notification->showMessage(tr("Unable to open the URL."));
+ }
+}
+
+void ImgS3Uploader::copyURL() {
+ QApplication::clipboard()->setText(m_imageURL.toString());
+ m_notification->showMessage(tr("URL copied to clipboard."));
+}
+
+void ImgS3Uploader::openDeleteURL()
+{
+ bool successful = QDesktopServices::openUrl(m_deleteImageURL);
+ if (!successful) {
+ m_notification->showMessage(tr("Unable to open the URL."));
+ }
+}
+
+void ImgS3Uploader::copyImage() {
+ QApplication::clipboard()->setPixmap(m_pixmap);
+ m_notification->showMessage(tr("Screenshot copied to clipboard."));
+}
diff --git a/src/tools/imgs3/imgs3uploader.h b/src/tools/imgs3/imgs3uploader.h
new file mode 100644
index 00000000..4be2f95a
--- /dev/null
+++ b/src/tools/imgs3/imgs3uploader.h
@@ -0,0 +1,73 @@
+// Copyright(c) 2017-2019 Alejandro Sirgo Rica & Contributors
+//
+// This file is part of Flameshot.
+//
+// Flameshot is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// Flameshot is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with Flameshot. If not, see .
+
+#pragma once
+
+#include
+#include
+
+class QNetworkReply;
+class QNetworkAccessManager;
+class QHBoxLayout;
+class QVBoxLayout;
+class QLabel;
+class LoadSpinner;
+class QPushButton;
+class QUrl;
+class NotificationWidget;
+
+class ImgS3Uploader : public QWidget {
+ Q_OBJECT
+public:
+ explicit ImgS3Uploader(const QPixmap &capture, QWidget *parent = nullptr);
+
+private slots:
+ void handleReply(QNetworkReply *reply);
+ void handleCredsReply(QNetworkReply *reply);
+ void startDrag();
+
+ void openURL();
+ void copyURL();
+ void openDeleteURL();
+ void copyImage();
+
+private:
+ void uploadToS3(QJsonDocument &response);
+
+private:
+ QString m_hostName;
+ QPixmap m_pixmap;
+ QNetworkAccessManager *m_NetworkAM;
+ QNetworkAccessManager *m_NetworkAMCreds;
+
+ QVBoxLayout *m_vLayout;
+ QHBoxLayout *m_hLayout;
+ // loading
+ QLabel *m_infoLabel;
+ LoadSpinner *m_spinner;
+ // uploaded
+ QPushButton *m_openUrlButton;
+ QPushButton *m_openDeleteUrlButton;
+ QPushButton *m_copyUrlButton;
+ QPushButton *m_toClipboardButton;
+ QUrl m_imageURL;
+ QUrl m_deleteImageURL;
+ NotificationWidget *m_notification;
+
+ void upload();
+ void onUploadOk();
+};
diff --git a/src/tools/imgs3/imgs3uploadertool.cpp b/src/tools/imgs3/imgs3uploadertool.cpp
new file mode 100644
index 00000000..e803df5e
--- /dev/null
+++ b/src/tools/imgs3/imgs3uploadertool.cpp
@@ -0,0 +1,58 @@
+// Copyright(c) 2017-2019 Alejandro Sirgo Rica & Contributors
+//
+// This file is part of Flameshot.
+//
+// Flameshot is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// Flameshot is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with Flameshot. If not, see .
+
+#include "imgs3uploadertool.h"
+#include "imgs3uploader.h"
+#include
+
+ImgS3UploaderTool::ImgS3UploaderTool(QObject *parent) : AbstractActionTool(parent) {
+
+}
+
+bool ImgS3UploaderTool::closeOnButtonPressed() const {
+ return true;
+}
+
+QIcon ImgS3UploaderTool::icon(const QColor &background, bool inEditor) const {
+ Q_UNUSED(inEditor);
+ return QIcon(iconPath(background) + "cloud-upload.svg");
+}
+QString ImgS3UploaderTool::name() const {
+ return tr("Image Uploader");
+}
+
+QString ImgS3UploaderTool::nameID() {
+ return QLatin1String("");
+}
+
+QString ImgS3UploaderTool::description() const {
+ return tr("Upload the selection to ImgS3");
+}
+
+QWidget* ImgS3UploaderTool::widget() {
+ return new ImgS3Uploader(capture);
+}
+
+CaptureTool* ImgS3UploaderTool::copy(QObject *parent) {
+ return new ImgS3UploaderTool(parent);
+}
+
+void ImgS3UploaderTool::pressed(const CaptureContext &context) {
+ capture = context.selectedScreenshotArea();
+ emit requestAction(REQ_CAPTURE_DONE_OK);
+ emit requestAction(REQ_ADD_EXTERNAL_WIDGETS);
+}
diff --git a/src/tools/imgs3/imgs3uploadertool.h b/src/tools/imgs3/imgs3uploadertool.h
new file mode 100644
index 00000000..43bc4d1f
--- /dev/null
+++ b/src/tools/imgs3/imgs3uploadertool.h
@@ -0,0 +1,43 @@
+// Copyright(c) 2017-2019 Alejandro Sirgo Rica & Contributors
+//
+// This file is part of Flameshot.
+//
+// Flameshot is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// Flameshot is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with Flameshot. If not, see .
+
+#pragma once
+
+#include "src/tools/abstractactiontool.h"
+
+class ImgS3UploaderTool : public AbstractActionTool {
+ Q_OBJECT
+public:
+ explicit ImgS3UploaderTool(QObject *parent = nullptr);
+
+ bool closeOnButtonPressed() const;
+
+ QIcon icon(const QColor &background, bool inEditor) const override;
+ QString name() const override;
+ static QString nameID();
+ QString description() const override;
+
+ QWidget* widget() override;
+
+ CaptureTool* copy(QObject *parent = nullptr) override;
+
+public slots:
+ void pressed(const CaptureContext &context) override;
+
+private:
+ QPixmap capture;
+};
diff --git a/src/tools/toolfactory.cpp b/src/tools/toolfactory.cpp
index 23c5032b..f76d7ca8 100644
--- a/src/tools/toolfactory.cpp
+++ b/src/tools/toolfactory.cpp
@@ -21,6 +21,7 @@
#include "copy/copytool.h"
#include "exit/exittool.h"
#include "imgur/imguruploadertool.h"
+#include "imgs3/imgs3uploadertool.h"
#include "line/linetool.h"
#include "marker/markertool.h"
#include "move/movetool.h"
@@ -59,7 +60,8 @@ CaptureTool* ToolFactory::CreateTool(
tool = new ExitTool(parent);
break;
case CaptureButton::TYPE_IMAGEUPLOADER:
- tool = new ImgurUploaderTool(parent);
+// tool = new ImgurUploaderTool(parent);
+ tool = new ImgS3UploaderTool(parent);
break;
case CaptureButton::TYPE_DRAWER:
tool = new LineTool(parent);