Preparing for upstream merge

This commit is contained in:
Jeremy Borgman
2020-10-20 06:53:59 -05:00
parent ffb119fabb
commit 62466d6581
42 changed files with 308 additions and 1961 deletions

View File

@@ -2,12 +2,12 @@ name: Building(CMake)
on:
push:
branches: [ master, master_nc_merge_upstream_test ]
branches: [ master ]
paths-ignore:
- 'README.md'
- 'LICENSE'
pull_request:
branches: [ master, master_nc_merge_upstream_test ]
branches: [ master ]
paths-ignore:
- 'README.md'
- 'LICENSE'

View File

@@ -4,7 +4,7 @@ cmake_minimum_required(VERSION 3.13)
# This can be read from ${PROJECT_NAME} after project() is called
project(
flameshot
VERSION 0.8.5.2
VERSION 0.8.5
LANGUAGES CXX)
set(PROJECT_NAME_CAPITALIZED "Flameshot")

View File

@@ -278,36 +278,6 @@ some Linux distributions:
Alternatively, in case you don't want to have a systray, you can always call Flameshot from the terminal. See [Usage section](#usage).
### S3 bucket configuration
S3 bucket credentials are placed in the file `config.ini` and cannot be configured with UI.
This file is not included into installation and should be placed into the installation directory manually.
On `linux` systems it can be placed at `/etc/flameshot/config.ini`.
You can also add `proxy` server settings. If you don't need a proxy server just remove or comment lines with a proxy settings.
Configuration file example:
```
[General]
HTTP_PROXY_HOST=10.0.0.1
HTTP_PROXY_PORT=3128
; No authentification USER and PASSWORD should be empty
HTTP_PROXY_USER=
HTTP_PROXY_PASSWORD=
HTTP_PROXY_TYPE=0
; Proxy Types (0 is default):
; 0 Proxy is determined based on the application proxy set using setApplicationProxy()
; 1 Socks5 proxying is used
; 3 HTTP transparent proxying is used
; 4 Proxying for HTTP requests only
; 5 Proxying for FTP requests only
[S3]
S3_CREDS_URL=https://api.img.example.com/
S3_X_API_KEY=seckret_key
```
## Compilation

View File

@@ -39,8 +39,8 @@ artifacts:
- path: build\artifact.zip
name: archive
#deploy:
#- provider: Webhook
# url: https://app.signpath.io/API/v1/042f605f-b378-45d8-ad16-b7695b071036/Integrations/AppVeyor?ProjectSlug=flameshot&SigningPolicySlug=test-signing
# authorization:
# secure: G5nNnkfRSJ+EEx+7LlUSSoEyoL+pHYItvjrNxbWITE7RB+cm9qzuHRdwmrZdEDjdVCLZ2TkNawynMxYcGMZAQA==
deploy:
- provider: Webhook
url: https://app.signpath.io/API/v1/042f605f-b378-45d8-ad16-b7695b071036/Integrations/AppVeyor?ProjectSlug=flameshot&SigningPolicySlug=test-signing
authorization:
secure: G5nNnkfRSJ+EEx+7LlUSSoEyoL+pHYItvjrNxbWITE7RB+cm9qzuHRdwmrZdEDjdVCLZ2TkNawynMxYcGMZAQA==

View File

@@ -12,5 +12,4 @@ target_sources(
visualseditor.cpp
shortcutswidget.cpp
setshortcutwidget.cpp
uploadstorageconfig.cpp
)

View File

@@ -20,7 +20,6 @@
#include "src/config/geneneralconf.h"
#include "src/config/shortcutswidget.h"
#include "src/config/strftimechooserwidget.h"
#include "src/config/uploadstorageconfig.h"
#include "src/config/visualseditor.h"
#include "src/utils/colorutils.h"
#include "src/utils/confighandler.h"
@@ -77,12 +76,6 @@ ConfigWindow::ConfigWindow(QWidget* parent)
m_shortcuts = new ShortcutsWidget();
addTab(m_shortcuts, QIcon(modifier + "shortcut.svg"), tr("Shortcuts"));
// upload storage configuration
m_uploadStorageConfig = new UploadStorageConfig();
addTab(m_uploadStorageConfig,
QIcon(modifier + "cloud-upload.svg"),
tr("Storage"));
// connect update sigslots
connect(this,
&ConfigWindow::updateChildren,

View File

@@ -24,7 +24,6 @@ class ShortcutsWidget;
class GeneneralConf;
class QFileSystemWatcher;
class VisualsEditor;
class UploadStorageConfig;
class ConfigWindow : public QTabWidget
{
@@ -42,7 +41,6 @@ private:
FileNameEditor* m_filenameEditor;
ShortcutsWidget* m_shortcuts;
GeneneralConf* m_generalConfig;
UploadStorageConfig* m_uploadStorageConfig;
VisualsEditor* m_visuals;
QFileSystemWatcher* m_configWatcher;
};

View File

@@ -1,72 +0,0 @@
// Copyright(c) 2020 Yurii Puchkov at Namecheap & 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 <http://www.gnu.org/licenses/>.
#include "uploadstorageconfig.h"
#include "src/tools/storage/imgstorages.h"
#include "src/tools/storage/storagemanager.h"
#include "src/utils/confighandler.h"
#include <QCheckBox>
#include <QGroupBox>
#include <QRadioButton>
#include <QVBoxLayout>
UploadStorageConfig::UploadStorageConfig(QWidget* parent)
: QWidget(parent)
{
m_layout = new QVBoxLayout(this);
m_layout->setAlignment(Qt::AlignTop);
QGroupBox* groupBox = new QGroupBox(tr("Upload storage"));
// TODO - remove dependency injection (s3 & imgur)
// imgur
QRadioButton* storageImgUr = new QRadioButton(tr("Imgur storage"));
connect(storageImgUr, &QCheckBox::clicked, [](bool checked) {
ConfigHandler().setUploadStorage(SCREENSHOT_STORAGE_TYPE_IMGUR);
});
// s3
QRadioButton* storageImgS3 = new QRadioButton(
tr("S3 storage (require config.ini file with s3 credentials)"));
connect(storageImgS3, &QCheckBox::clicked, [](bool checked) {
ConfigHandler().setUploadStorage(SCREENSHOT_STORAGE_TYPE_S3);
});
StorageManager storageManager;
if (storageManager.storageLocked()) {
ConfigHandler().setUploadStorage(storageManager.storageDefault());
storageImgUr->setDisabled(true);
storageImgS3->setDisabled(true);
}
// set current storage radiobutton active
if (ConfigHandler().uploadStorage() == SCREENSHOT_STORAGE_TYPE_IMGUR) {
storageImgUr->setChecked(true);
} else {
storageImgS3->setChecked(true);
}
// draw configuration options for uploadStorage
QVBoxLayout* vbox = new QVBoxLayout;
vbox->addWidget(storageImgUr);
vbox->addWidget(storageImgS3);
vbox->addStretch(1);
groupBox->setLayout(vbox);
m_layout->addWidget(groupBox);
}

View File

@@ -1,36 +0,0 @@
// Copyright(c) 2020 Yurii Puchkov at Namecheap & 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 <http://www.gnu.org/licenses/>.
#ifndef FLAMESHOT_UPLOADSTORAGECONFIG_H
#define FLAMESHOT_UPLOADSTORAGECONFIG_H
#include <QObject>
#include <QWidget>
class QVBoxLayout;
class UploadStorageConfig : public QWidget
{
Q_OBJECT
public:
explicit UploadStorageConfig(QWidget* parent = nullptr);
private:
QVBoxLayout* m_layout;
};
#endif // FLAMESHOT_UPLOADSTORAGECONFIG_H

View File

@@ -6,22 +6,10 @@ target_sources(flameshot PRIVATE copy/copytool.h copy/copytool.cpp)
target_sources(flameshot PRIVATE exit/exittool.h exit/exittool.cpp)
target_sources(
flameshot
PRIVATE storage/storagemanager.h
storage/storagemanager.cpp
storage/imguploader.h
storage/imguploadertool.h
storage/imguploader.cpp
storage/imguploadertool.cpp
storage/imgur/imguruploader.h
storage/imgur/imguruploadertool.h
storage/imgur/imguruploader.cpp
storage/imgur/imguruploadertool.cpp
storage/s3/imgs3settings.h
storage/s3/imgs3settings.cpp
storage/s3/imgs3uploader.h
storage/s3/imgs3uploadertool.h
storage/s3/imgs3uploader.cpp
storage/s3/imgs3uploadertool.cpp
PRIVATE imgur/imguruploader.h
imgur/imguruploadertool.h
imgur/imguruploader.cpp
imgur/imguruploadertool.cpp
)
target_sources(
flameshot

View File

@@ -0,0 +1,213 @@
// 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 <http://www.gnu.org/licenses/>.
#include "imguruploader.h"
#include "src/utils/confighandler.h"
#include "src/utils/filenamehandler.h"
#include "src/utils/systemnotification.h"
#include "src/widgets/imagelabel.h"
#include "src/widgets/loadspinner.h"
#include "src/widgets/notificationwidget.h"
#include <QApplication>
#include <QBuffer>
#include <QClipboard>
#include <QCursor>
#include <QDesktopServices>
#include <QDrag>
#include <QGuiApplication>
#include <QHBoxLayout>
#include <QJsonDocument>
#include <QJsonObject>
#include <QLabel>
#include <QMimeData>
#include <QNetworkAccessManager>
#include <QNetworkReply>
#include <QNetworkRequest>
#include <QPushButton>
#include <QRect>
#include <QScreen>
#include <QShortcut>
#include <QTimer>
#include <QUrlQuery>
#include <QVBoxLayout>
ImgurUploader::ImgurUploader(const QPixmap& capture, QWidget* parent)
: QWidget(parent)
, m_pixmap(capture)
{
setWindowTitle(tr("Upload to Imgur"));
setWindowIcon(QIcon(":img/app/flameshot.svg"));
#if (QT_VERSION >= QT_VERSION_CHECK(5, 10, 0))
QRect position = frameGeometry();
QScreen* screen = QGuiApplication::screenAt(QCursor::pos());
position.moveCenter(screen->availableGeometry().center());
move(position.topLeft());
#endif
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,
&ImgurUploader::handleReply);
setAttribute(Qt::WA_DeleteOnClose);
upload();
// QTimer::singleShot(2000, this, &ImgurUploader::onUploadOk); // testing
}
void ImgurUploader::handleReply(QNetworkReply* reply)
{
m_spinner->deleteLater();
if (reply->error() == QNetworkReply::NoError) {
QJsonDocument response = QJsonDocument::fromJson(reply->readAll());
QJsonObject json = response.object();
QJsonObject data = json[QStringLiteral("data")].toObject();
m_imageURL.setUrl(data[QStringLiteral("link")].toString());
m_deleteImageURL.setUrl(
QStringLiteral("https://imgur.com/delete/%1")
.arg(data[QStringLiteral("deletehash")].toString()));
if (ConfigHandler().copyAndCloseAfterUploadEnabled()) {
QApplication::clipboard()->setText(m_imageURL.toString());
SystemNotification().sendMessage(
QObject::tr("URL copied to clipboard."));
close();
} else {
onUploadOk();
}
} else {
m_infoLabel->setText(reply->errorString());
}
new QShortcut(Qt::Key_Escape, this, SLOT(close()));
}
void ImgurUploader::startDrag()
{
QMimeData* mimeData = new QMimeData;
mimeData->setUrls(QList<QUrl>{ 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 ImgurUploader::upload()
{
QByteArray byteArray;
QBuffer buffer(&byteArray);
m_pixmap.save(&buffer, "PNG");
QUrlQuery urlQuery;
urlQuery.addQueryItem(QStringLiteral("title"),
QStringLiteral("flameshot_screenshot"));
QString description = FileNameHandler().parsedPattern();
urlQuery.addQueryItem(QStringLiteral("description"), description);
QUrl url(QStringLiteral("https://api.imgur.com/3/image"));
url.setQuery(urlQuery);
QNetworkRequest request(url);
request.setHeader(QNetworkRequest::ContentTypeHeader,
"application/application/x-www-form-urlencoded");
request.setRawHeader(
"Authorization",
QStringLiteral("Client-ID %1").arg(IMGUR_CLIENT_ID).toUtf8());
m_NetworkAM->post(request, byteArray);
}
void ImgurUploader::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, &ImgurUploader::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, &ImgurUploader::copyURL);
connect(
m_openUrlButton, &QPushButton::clicked, this, &ImgurUploader::openURL);
connect(m_openDeleteUrlButton,
&QPushButton::clicked,
this,
&ImgurUploader::openDeleteURL);
connect(m_toClipboardButton,
&QPushButton::clicked,
this,
&ImgurUploader::copyImage);
}
void ImgurUploader::openURL()
{
bool successful = QDesktopServices::openUrl(m_imageURL);
if (!successful) {
m_notification->showMessage(tr("Unable to open the URL."));
}
}
void ImgurUploader::copyURL()
{
QApplication::clipboard()->setText(m_imageURL.toString());
m_notification->showMessage(tr("URL copied to clipboard."));
}
void ImgurUploader::openDeleteURL()
{
bool successful = QDesktopServices::openUrl(m_deleteImageURL);
if (!successful) {
m_notification->showMessage(tr("Unable to open the URL."));
}
}
void ImgurUploader::copyImage()
{
QApplication::clipboard()->setPixmap(m_pixmap);
m_notification->showMessage(tr("Screenshot copied to clipboard."));
}

View File

@@ -17,7 +17,6 @@
#pragma once
#include "../imguploader.h"
#include <QUrl>
#include <QWidget>
@@ -31,21 +30,39 @@ class QPushButton;
class QUrl;
class NotificationWidget;
class ImgurUploader : public ImgUploader
class ImgurUploader : public QWidget
{
Q_OBJECT
public:
explicit ImgurUploader(const QPixmap& capture, QWidget* parent = nullptr);
void upload();
private slots:
void handleReply(QNetworkReply* reply);
void startDrag();
protected slots:
void deleteImageOnStorage();
void openURL();
void copyURL();
void openDeleteURL();
void copyImage();
// class members
private:
QPixmap m_pixmap;
QNetworkAccessManager* m_NetworkAM;
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();
};

View File

@@ -20,14 +20,29 @@
#include <QPainter>
ImgurUploaderTool::ImgurUploaderTool(QObject* parent)
: ImgUploaderTool(parent)
: AbstractActionTool(parent)
{}
bool ImgurUploaderTool::closeOnButtonPressed() const
{
return true;
}
QIcon ImgurUploaderTool::icon(const QColor& background, bool inEditor) const
{
Q_UNUSED(inEditor);
return QIcon(iconPath(background) + "cloud-upload.svg");
}
QString ImgurUploaderTool::name() const
{
return tr("Image Uploader");
}
ToolType ImgurUploaderTool::nameID() const
{
return ToolType::IMGUR;
}
QString ImgurUploaderTool::description() const
{
return tr("Upload the selection to Imgur");
@@ -35,12 +50,17 @@ QString ImgurUploaderTool::description() const
QWidget* ImgurUploaderTool::widget()
{
ImgurUploader* p = new ImgurUploader(capture());
p->upload();
return p;
return new ImgurUploader(capture);
}
CaptureTool* ImgurUploaderTool::copy(QObject* parent)
{
return new ImgurUploaderTool(parent);
}
void ImgurUploaderTool::pressed(const CaptureContext& context)
{
capture = context.selectedScreenshotArea();
emit requestAction(REQ_CAPTURE_DONE_OK);
emit requestAction(REQ_ADD_EXTERNAL_WIDGETS);
}

View File

@@ -17,18 +17,30 @@
#pragma once
#include "src/tools/storage/imguploadertool.h"
#include "src/tools/abstractactiontool.h"
class ImgurUploaderTool : public ImgUploaderTool
class ImgurUploaderTool : public AbstractActionTool
{
Q_OBJECT
public:
explicit ImgurUploaderTool(QObject* parent = nullptr);
bool closeOnButtonPressed() const;
QIcon icon(const QColor& background, bool inEditor) const override;
QString name() const override;
QString description() const override;
QWidget* widget() override;
CaptureTool* copy(QObject* parent = nullptr) override;
protected:
ToolType nameID() const override;
public slots:
void pressed(const CaptureContext& context) override;
private:
QPixmap capture;
};

View File

@@ -85,9 +85,8 @@ void PixelateTool::process(QPainter& painter,
scene.render(&painter, selection, QRectF());
blur->setBlurRadius(12);
// multiple repeat for make blur effect stronger
for (int cnt = 100; cnt > 0; cnt--) {
scene.render(&painter, selection, QRectF());
}
scene.render(&painter, selection, QRectF());
} else {
int width = selection.width() * (0.5 / qMax(1, m_thickness));
int height = selection.height() * (0.5 / qMax(1, m_thickness));

View File

@@ -1,7 +0,0 @@
#ifndef IMGSTORAGES_H
#define IMGSTORAGES_H
#define SCREENSHOT_STORAGE_TYPE_S3 "s3"
#define SCREENSHOT_STORAGE_TYPE_IMGUR "imgur"
#endif // IMGSTORAGES_H

View File

@@ -1,207 +0,0 @@
// 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 <http://www.gnu.org/licenses/>.
#include "imguploader.h"
#include "src/utils/confighandler.h"
#include "src/widgets/imagelabel.h"
#include "src/widgets/loadspinner.h"
#include "src/widgets/notificationwidget.h"
#include <QApplication>
#include <QClipboard>
#include <QCursor>
#include <QDesktopServices>
#include <QDrag>
#include <QGuiApplication>
#include <QJsonDocument>
#include <QJsonObject>
#include <QLabel>
#include <QMimeData>
#include <QNetworkAccessManager>
#include <QPushButton>
#include <QRect>
#include <QScreen>
#include <QShortcut>
#include <QTimer>
#include <QUrlQuery>
#include <QVBoxLayout>
ImgUploader::ImgUploader(const QPixmap& capture, QWidget* parent)
: QWidget(parent)
, m_pixmap(capture)
{
init(tr("Upload image to S3"), tr("Uploading Image"));
}
ImgUploader::ImgUploader(QWidget* parent)
: QWidget(parent)
{
init(tr("Upload image"), tr("Uploading Image"));
}
void ImgUploader::init(const QString& title, const QString& label)
{
m_imageLabel = nullptr;
m_spinner = nullptr;
resultStatus = false;
setWindowTitle(title);
setWindowIcon(QIcon(":img/app/flameshot.svg"));
#if (QT_VERSION >= QT_VERSION_CHECK(5, 10, 0))
QRect position = frameGeometry();
QScreen* screen = QGuiApplication::screenAt(QCursor::pos());
position.moveCenter(screen->availableGeometry().center());
move(position.topLeft());
#endif
m_spinner = new LoadSpinner(this);
m_spinner->setColor(ConfigHandler().uiMainColorValue());
m_spinner->start();
m_infoLabel = new QLabel(label);
m_infoLabel->setAlignment(Qt::AlignCenter);
m_vLayout = new QVBoxLayout();
setLayout(m_vLayout);
m_vLayout->addWidget(m_spinner, 0, Qt::AlignHCenter);
m_vLayout->addWidget(m_infoLabel);
setAttribute(Qt::WA_DeleteOnClose);
}
void ImgUploader::openURL()
{
bool successful = QDesktopServices::openUrl(imageUrl());
if (!successful) {
m_notification->showMessage(tr("Unable to open the URL."));
}
}
void ImgUploader::copyURL()
{
QApplication::clipboard()->setText(imageUrl().toString());
m_notification->showMessage(tr("URL copied to clipboard."));
}
void ImgUploader::copyImage()
{
QApplication::clipboard()->setPixmap(m_pixmap);
m_notification->showMessage(tr("Screenshot copied to clipboard."));
}
void ImgUploader::deleteImageOnStorage()
{
if (nullptr != m_imageLabel) {
m_imageLabel->hide();
}
m_spinner->show();
setInfoLabelText(tr("Deleting image..."));
deleteResource(m_storageImageName, m_deleteToken);
}
void ImgUploader::startDrag()
{
QMimeData* mimeData = new QMimeData;
mimeData->setUrls(QList<QUrl>{ 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 ImgUploader::hideSpinner()
{
if (nullptr != m_spinner) {
m_spinner->hide();
}
if (nullptr != m_imageLabel) {
m_imageLabel->hide();
}
}
void ImgUploader::setInfoLabelText(const QString& infoText)
{
m_infoLabel->setText(infoText);
m_infoLabel->show();
}
const QPixmap& ImgUploader::pixmap()
{
return m_pixmap;
}
void ImgUploader::onUploadOk()
{
hideSpinner();
m_notification = new NotificationWidget();
m_vLayout->addWidget(m_notification);
if (nullptr == m_imageLabel) {
m_imageLabel = new ImageLabel();
m_imageLabel->setScreenshot(pixmap());
m_imageLabel->setSizePolicy(QSizePolicy::Expanding,
QSizePolicy::Expanding);
connect(m_imageLabel,
&ImageLabel::dragInitiated,
this,
&ImgUploader::startDrag);
m_vLayout->addWidget(m_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_deleteImageOnStorage = 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_deleteImageOnStorage);
m_hLayout->addWidget(m_toClipboardButton);
connect(
m_copyUrlButton, &QPushButton::clicked, this, &ImgUploader::copyURL);
connect(
m_openUrlButton, &QPushButton::clicked, this, &ImgUploader::openURL);
connect(m_deleteImageOnStorage,
&QPushButton::clicked,
this,
&ImgUploader::deleteImageOnStorage);
connect(m_toClipboardButton,
&QPushButton::clicked,
this,
&ImgUploader::copyImage);
}
void ImgUploader::setImageUrl(const QUrl& imageURL)
{
m_imageURL = imageURL;
}
const QUrl& ImgUploader::imageUrl()
{
return m_imageURL;
}
void ImgUploader::showNotificationMessage(const QString& notificationMessage)
{
m_notification->showMessage(notificationMessage);
}

View File

@@ -1,95 +0,0 @@
// 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 <http://www.gnu.org/licenses/>.
#pragma once
#include "imgstorages.h"
#include "s3/imgs3settings.h"
#include <QUrl>
#include <QWidget>
class QNetworkReply;
class QNetworkProxy;
class QNetworkAccessManager;
class QHBoxLayout;
class QVBoxLayout;
class QLabel;
class LoadSpinner;
class QPushButton;
class QUrl;
class NotificationWidget;
class ImageLabel;
class ImgUploader : public QWidget
{
Q_OBJECT
public:
explicit ImgUploader(const QPixmap& capture, QWidget* parent = nullptr);
explicit ImgUploader(QWidget* parent = nullptr);
virtual void upload(){};
virtual void deleteResource(const QString&, const QString&){};
protected:
const QPixmap& pixmap();
void setImageUrl(const QUrl&);
const QUrl& imageUrl();
void onUploadOk();
void hideSpinner();
void setInfoLabelText(const QString&);
void showNotificationMessage(const QString&);
public slots:
virtual void openURL();
virtual void copyURL();
virtual void copyImage();
virtual void deleteImageOnStorage();
virtual void startDrag();
private:
void init(const QString& title, const QString& label);
// class members
private:
QPixmap m_pixmap;
QUrl m_imageURL;
ImageLabel* m_imageLabel;
NotificationWidget* m_notification;
QVBoxLayout* m_vLayout;
QHBoxLayout* m_hLayout;
// loading
LoadSpinner* m_spinner;
QLabel* m_infoLabel;
// uploaded
QPushButton* m_openUrlButton;
QPushButton* m_copyUrlButton;
QPushButton* m_toClipboardButton;
QPushButton* m_deleteImageOnStorage;
protected:
// bool m_success;
// Temporary variables
QString m_deleteToken;
QString m_storageImageName;
public:
bool resultStatus;
};

View File

@@ -1,43 +0,0 @@
#include "imguploadertool.h"
ImgUploaderTool::ImgUploaderTool(QObject* parent)
: AbstractActionTool(parent)
{}
void ImgUploaderTool::setCapture(const QPixmap& pixmap)
{
m_capture = pixmap;
}
void ImgUploaderTool::pressed(const CaptureContext& context)
{
m_capture = context.selectedScreenshotArea();
emit requestAction(REQ_CAPTURE_DONE_OK);
emit requestAction(REQ_ADD_EXTERNAL_WIDGETS);
}
QString ImgUploaderTool::name() const
{
return tr("Image uploader tool");
}
const QPixmap& ImgUploaderTool::capture()
{
return m_capture;
}
QIcon ImgUploaderTool::icon(const QColor& background, bool inEditor) const
{
Q_UNUSED(inEditor);
return QIcon(iconPath(background) + "cloud-upload.svg");
}
bool ImgUploaderTool::closeOnButtonPressed() const
{
return true;
}
ToolType ImgUploaderTool::nameID() const
{
return ToolType::UPLOAD;
}

View File

@@ -1,30 +0,0 @@
#ifndef IMGUPLOADERTOOL_H
#define IMGUPLOADERTOOL_H
#include "src/tools/abstractactiontool.h"
class ImgUploaderTool : public AbstractActionTool
{
Q_OBJECT
public:
explicit ImgUploaderTool(QObject* parent = nullptr);
bool closeOnButtonPressed() const;
QString name() const override;
QIcon icon(const QColor& background, bool inEditor) const override;
void setCapture(const QPixmap& pixmap);
const QPixmap& capture();
public slots:
void pressed(const CaptureContext& context) override;
protected:
ToolType nameID() const override;
private:
QPixmap m_capture;
};
#endif // IMGUPLOADERTOOL_H

View File

@@ -1,126 +0,0 @@
// 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 <http://www.gnu.org/licenses/>.
#include "imguruploader.h"
#include "src/core/controller.h"
#include "src/utils/confighandler.h"
#include "src/utils/filenamehandler.h"
#include "src/utils/history.h"
#include "src/utils/systemnotification.h"
#include "src/widgets/imagelabel.h"
#include "src/widgets/loadspinner.h"
#include "src/widgets/notificationwidget.h"
#include <QApplication>
#include <QBuffer>
#include <QClipboard>
#include <QDesktopServices>
#include <QJsonDocument>
#include <QJsonObject>
#include <QLabel>
#include <QMimeData>
#include <QNetworkAccessManager>
#include <QNetworkReply>
#include <QNetworkRequest>
#include <QShortcut>
#include <QUrlQuery>
#include <QVBoxLayout>
ImgurUploader::ImgurUploader(const QPixmap& capture, QWidget* parent)
: ImgUploader(capture, parent)
{
setWindowTitle(tr("Upload to Imgur"));
m_NetworkAM = new QNetworkAccessManager(this);
connect(m_NetworkAM,
&QNetworkAccessManager::finished,
this,
&ImgurUploader::handleReply);
}
void ImgurUploader::handleReply(QNetworkReply* reply)
{
if (reply->error() == QNetworkReply::NoError) {
QJsonDocument response = QJsonDocument::fromJson(reply->readAll());
QJsonObject json = response.object();
QJsonObject data = json[QStringLiteral("data")].toObject();
setImageUrl(data[QStringLiteral("link")].toString());
m_deleteToken = data[QStringLiteral("deletehash")].toString();
m_deleteImageURL.setUrl(
QStringLiteral("https://imgur.com/delete/%1").arg(m_deleteToken));
// save history
QString imageName = imageUrl().toString();
int lastSlash = imageName.lastIndexOf("/");
if (lastSlash >= 0) {
imageName = imageName.mid(lastSlash + 1);
}
m_storageImageName = imageName;
// save image to history
History history;
imageName = history.packFileName(
SCREENSHOT_STORAGE_TYPE_IMGUR, m_deleteToken, imageName);
history.save(pixmap(), imageName);
resultStatus = true;
if (ConfigHandler().copyAndCloseAfterUploadEnabled()) {
QApplication::clipboard()->setText(imageUrl().toString());
SystemNotification().sendMessage(
QObject::tr("URL copied to clipboard."));
Controller::getInstance()->updateRecentScreenshots();
close();
} else {
onUploadOk();
}
} else {
setInfoLabelText(reply->errorString());
}
new QShortcut(Qt::Key_Escape, this, SLOT(close()));
}
void ImgurUploader::upload()
{
QByteArray byteArray;
QBuffer buffer(&byteArray);
pixmap().save(&buffer, "PNG");
QUrlQuery urlQuery;
urlQuery.addQueryItem(QStringLiteral("title"),
QStringLiteral("flameshot_screenshot"));
QString description = FileNameHandler().parsedPattern();
urlQuery.addQueryItem(QStringLiteral("description"), description);
QUrl url(QStringLiteral("https://api.imgur.com/3/image"));
url.setQuery(urlQuery);
QNetworkRequest request(url);
request.setHeader(QNetworkRequest::ContentTypeHeader,
"application/application/x-www-form-urlencoded");
request.setRawHeader(
"Authorization",
QStringLiteral("Client-ID %1").arg(IMGUR_CLIENT_ID).toUtf8());
m_NetworkAM->post(request, byteArray);
}
void ImgurUploader::deleteImageOnStorage()
{
bool successful = QDesktopServices::openUrl(m_deleteImageURL);
if (!successful) {
showNotificationMessage(tr("Unable to open the URL."));
}
}

View File

@@ -1,135 +0,0 @@
# Flameshot Amazon S3 Storage
Flameshot S3 storage is using presigned multipart upload, the idea is explained here:
* [Upload files to AWS S3 using pre-signed POST data and a Lambda function](Upload files to AWS S3 using pre-signed POST data and a Lambda function)
* [Uploading Objects to S3 Using One-Time Presigned URLs](https://medium.com/@laardee/uploading-objects-to-s3-using-one-time-presigned-urls-4374943f0801)
Supported operations:
- upload
- delete
## Upload
### Step 1 - get one-time presigned url
C++ example:
```c++
QUrl creds(m_s3Settings.credsUrl());
QNetworkRequest requestCreds(creds);
if (m_s3Settings.xApiKey().length() > 0) {
requestCreds.setRawHeader(
QByteArray("X-API-Key"),
QByteArray(m_s3Settings.xApiKey().toLocal8Bit()));
}
m_NetworkAMGetCreds->get(requestCreds);
```
Shell example:
```shell script
curl --location --request GET "https://api.img.examples.flameshot.org/v2/image/" \
--header "X-API-Key: aws-secret-key"
```
Response example:
```json
{
"formData": {
"url": "https://screenshots-example-flameshot.org.s3-accelerate.amazonaws.com",
"fields": {
"acl": "private",
"Content-Type": "image/png",
"Key": "some-key.png",
"tagging": "<Tagging><TagSet><Tag><Key>deleteToken</Key><Value>some-value</Value></Tag></TagSet></Tagging>",
"bucket": "screenshots-example-flameshot.org",
"X-Amz-Algorithm": "AWS4-HMAC-SHA256",
"X-Amz-Credential": "some-data/eu-central-1/s3/aws4_request",
"X-Amz-Date": "20200929T100000Z",
"X-Amz-Security-Token": "some-security-token",
"Policy": "some-policy",
"X-Amz-Signature": "some-signature"
}
},
"resultURL": "https://img.examples.flameshot.org/some-key.png",
"deleteToken": "some-delete-token-x"
}
```
* `resultURL` - url to s3 bucket to upload image directly to Amazon
* `deleteToken` - contains token which will be required for implementing `DELETE` operation.
### Step 2 - do direct multi-part upload to the s3 bucket
Upload to S3 bucket
Send `POST` request to Amazon S3, based on the results from the `Step 1`.
C++ example:
```c++
void ImgS3Uploader::uploadToS3(QJsonDocument& response)
{
// set paramets from "fields"
QHttpMultiPart* multiPart =
new QHttpMultiPart(QHttpMultiPart::FormDataType);
// read JSON response
QJsonObject json = response.object();
QString resultUrl = json["resultURL"].toString();
QJsonObject formData = json["formData"].toObject();
QString url = formData["url"].toString();
m_deleteToken = json["deleteToken"].toString();
QJsonObject fields = formData["fields"].toObject();
foreach (auto key, fields.keys()) {
QString field = fields[key].toString();
QHttpPart part;
part.setHeader(QNetworkRequest::ContentDispositionHeader,
QVariant("form-data; name=\"" + key + "\""));
part.setBody(field.toLatin1());
multiPart->append(part);
}
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);
pixmap().save(&buffer, "PNG");
imagePart.setBody(byteArray);
multiPart->append(imagePart);
setImageUrl(QUrl(resultUrl));
QUrl qUrl(url);
QNetworkRequest request(qUrl);
// upload
m_NetworkAMUpload->post(request, multiPart);
}
```
# Delete
Shell example:
```shell script
curl --location --request DELETE 'https://api.img.rnd.namecheap.net/v2/image/sH5M3zETezZgA95mmKCMfq.png' \
--header 'X-API-Key: aws-secret-key' \
--header 'Authorization: Bearer some-delete-token-x'
```
Where `some-delete-token-x` is a value from the request from the `step 1`
C++ example:
```c++
QNetworkRequest request;
m_storageImageName = fileName;
m_deleteToken = deleteToken;
request.setUrl(m_s3Settings.credsUrl().toUtf8() + fileName);
request.setRawHeader("X-API-Key", m_s3Settings.xApiKey().toLatin1());
request.setRawHeader("Authorization", "Bearer " + deleteToken.toLatin1());
m_NetworkAMRemove->deleteResource(request);
```

View File

@@ -1,25 +0,0 @@
[General]
; Lock storage selection for the enterprise users
; (it will lock to the default storage)
STORAGE_LOCK=true
; PROXY SETTINGS
;HTTP_PROXY_HOST=0.0.0.0
;HTTP_PROXY_PORT=3128
; No authentification USER and PASSWORD should be empty
;HTTP_PROXY_USER=
;HTTP_PROXY_PASSWORD=
;HTTP_PROXY_TYPE=3
; Proxy Types (3 is default):
; 0 Proxy is determined based on the application proxy set using setApplicationProxy()
; 1 Socks5 proxying is used
; 3 HTTP transparent proxying is used
; 4 Proxying for HTTP requests only
; 5 Proxying for FTP requests only
[S3]
S3_URL=https://api.flameshot.org/
S3_CREDS_URL=https://api.img.flameshot.org/
S3_X_API_KEY=amazon-secret-key

View File

@@ -1,122 +0,0 @@
'use strict';
const uuid = require('short-uuid');
const AWS = require('aws-sdk');
AWS.config.update({ region: process.env.AWS_REGION || 'us-east-1' });
const s3 = new AWS.S3();
const cloudfront = new AWS.CloudFront();
const allowedImageType = 'png';
// Main Lambda entry point
exports.handler = async (event) => {
console.log('Event: ', event);
let result;
if (event.resource === '/v2/image/{fileName}' && event.httpMethod === 'DELETE') {
let token = (event.headers.Authorization && event.headers.Authorization.split(' ')[1]) || '';
result = await deleteObject(event.pathParameters.fileName, token);
if (result === false) {
return {
statusCode: 400,
isBase64Encoded: false,
headers: {
'Access-Control-Allow-Origin': '*'
},
body: 'Bad request'
};
}
} else {
result = await getUploadDetails(event.resource === '/v2/image' ? 2 : 1);
}
console.log('Result: ', result);
return {
statusCode: 200,
isBase64Encoded: false,
headers: {
'Access-Control-Allow-Origin': '*'
},
body: JSON.stringify(result)
};
};
const getUploadDetails = async function(version) {
const actionId = uuid.generate();
const deleteToken = uuid.generate();
const s3Params = {
Bucket: process.env.UploadBucket,
Fields: {
Key: `${actionId}.${allowedImageType}`,
},
Conditions: [
[ 'eq', '$acl', 'private' ],
[ 'eq', '$Content-Type', `image/${allowedImageType}` ],
[ 'content-length-range', 0, 10485760 ], //allows a file size from 0B to 10 MiB
],
Expires: 60,
};
if (version === 2) {
s3Params.Fields.tagging = getDeleteTags(deleteToken);
}
console.log('getUploadURL: ', s3Params);
const signedForm = await createPresignedPost(s3Params);
signedForm.url = `https://${process.env.UploadBucket}.s3-accelerate.amazonaws.com`;
signedForm.fields = Object.assign({
acl: 'private',
'Content-Type': `image/${allowedImageType}`,
}, signedForm.fields);
const uploadDetails = {
formData: signedForm,
resultURL: `${process.env.BasePath}${s3Params.Fields.Key}`
};
if (version === 2) {
uploadDetails.deleteToken = deleteToken;
}
return uploadDetails;
};
const deleteObject = async (key, token) => {
const s3ObjectParams = {Bucket: process.env.UploadBucket, Key: key};
const {TagSet: tags} = await s3.getObjectTagging(s3ObjectParams).promise();
const storedTokenInfo = tags.find(v => v.Key === 'deleteToken');
if (storedTokenInfo === undefined) {
console.log(`Unable to find storedTokenInfo for requested key "${key}"`);
return false;
}
if (storedTokenInfo.Value !== token) {
console.log(`storedTokenInfo != passed token: ${storedTokenInfo.Value} != ${token}`);
return false;
}
await s3.deleteObject(s3ObjectParams).promise();
await cloudfront.createInvalidation({
DistributionId: process.env.DistributionId,
InvalidationBatch: {
CallerReference: uuid.generate(),
Paths: {
Quantity: 1,
Items: [`/${key}`]
}
}
}).promise();
return {status: 'ok'}
};
const getDeleteTags = (token) => `<Tagging><TagSet><Tag><Key>deleteToken</Key><Value>${token}</Value></Tag></TagSet></Tagging>`;
const createPresignedPost = params =>
new Promise((resolve, reject) =>
s3.createPresignedPost( params, (err, data) => err ? reject(err) : resolve(data) )
);

View File

@@ -1,125 +0,0 @@
{
"name": "none",
"version": "1.0.0",
"lockfileVersion": 1,
"requires": true,
"dependencies": {
"any-base": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/any-base/-/any-base-1.1.0.tgz",
"integrity": "sha512-uMgjozySS8adZZYePpaWs8cxB9/kdzmpX6SgJZ+wbz1K5eYk5QMYDVJaZKhxyIHUdnnJkfR7SVgStgH7LkGUyg=="
},
"aws-sdk": {
"version": "2.700.0",
"resolved": "https://registry.npmjs.org/aws-sdk/-/aws-sdk-2.700.0.tgz",
"integrity": "sha512-faBkr/D3IavfL2mwst4/thiKsHkN8YCwU9927Mkiushbe7n4UXxlcNf7LnVxFyjr3WIf4KfziSw4bajRAiAjYA==",
"requires": {
"buffer": "4.9.2",
"events": "1.1.1",
"ieee754": "1.1.13",
"jmespath": "0.15.0",
"querystring": "0.2.0",
"sax": "1.2.1",
"url": "0.10.3",
"uuid": "3.3.2",
"xml2js": "0.4.19"
},
"dependencies": {
"uuid": {
"version": "3.3.2",
"resolved": "https://registry.npmjs.org/uuid/-/uuid-3.3.2.tgz",
"integrity": "sha512-yXJmeNaw3DnnKAOKJE51sL/ZaYfWJRl1pK9dr19YFCu0ObS231AB1/LbqTKRAQ5kw8A90rA6fr4riOUpTZvQZA=="
}
}
},
"base64-js": {
"version": "1.3.1",
"resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.3.1.tgz",
"integrity": "sha512-mLQ4i2QO1ytvGWFWmcngKO//JXAQueZvwEKtjgQFM4jIK0kU+ytMfplL8j+n5mspOfjHwoAg+9yhb7BwAHm36g=="
},
"buffer": {
"version": "4.9.2",
"resolved": "https://registry.npmjs.org/buffer/-/buffer-4.9.2.tgz",
"integrity": "sha512-xq+q3SRMOxGivLhBNaUdC64hDTQwejJ+H0T/NB1XMtTVEwNTrfFF3gAxiyW0Bu/xWEGhjVKgUcMhCrUy2+uCWg==",
"requires": {
"base64-js": "^1.0.2",
"ieee754": "^1.1.4",
"isarray": "^1.0.0"
}
},
"events": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/events/-/events-1.1.1.tgz",
"integrity": "sha1-nr23Y1rQmccNzEwqH1AEKI6L2SQ="
},
"ieee754": {
"version": "1.1.13",
"resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.1.13.tgz",
"integrity": "sha512-4vf7I2LYV/HaWerSo3XmlMkp5eZ83i+/CDluXi/IGTs/O1sejBNhTtnxzmRZfvOUqj7lZjqHkeTvpgSFDlWZTg=="
},
"isarray": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
"integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE="
},
"jmespath": {
"version": "0.15.0",
"resolved": "https://registry.npmjs.org/jmespath/-/jmespath-0.15.0.tgz",
"integrity": "sha1-o/Iiqarp+Wb10nx5ZRDigJF2Qhc="
},
"punycode": {
"version": "1.3.2",
"resolved": "https://registry.npmjs.org/punycode/-/punycode-1.3.2.tgz",
"integrity": "sha1-llOgNvt8HuQjQvIyXM7v6jkmxI0="
},
"querystring": {
"version": "0.2.0",
"resolved": "https://registry.npmjs.org/querystring/-/querystring-0.2.0.tgz",
"integrity": "sha1-sgmEkgO7Jd+CDadW50cAWHhSFiA="
},
"sax": {
"version": "1.2.1",
"resolved": "https://registry.npmjs.org/sax/-/sax-1.2.1.tgz",
"integrity": "sha1-e45lYZCyKOgaZq6nSEgNgozS03o="
},
"short-uuid": {
"version": "3.1.1",
"resolved": "https://registry.npmjs.org/short-uuid/-/short-uuid-3.1.1.tgz",
"integrity": "sha512-7dI69xtJYpTIbg44R6JSgrbDtZFuZ9vAwwmnF/L0PinykbFrhQ7V8omKsQcVw1TP0nYJ7uQp1PN6/aVMkzQFGQ==",
"requires": {
"any-base": "^1.1.0",
"uuid": "^3.3.2"
},
"dependencies": {
"uuid": {
"version": "3.4.0",
"resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz",
"integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A=="
}
}
},
"url": {
"version": "0.10.3",
"resolved": "https://registry.npmjs.org/url/-/url-0.10.3.tgz",
"integrity": "sha1-Ah5NnHcF8hu/N9A861h2dAJ3TGQ=",
"requires": {
"punycode": "1.3.2",
"querystring": "0.2.0"
}
},
"xml2js": {
"version": "0.4.19",
"resolved": "https://registry.npmjs.org/xml2js/-/xml2js-0.4.19.tgz",
"integrity": "sha512-esZnJZJOiJR9wWKMyuvSE1y6Dq5LCuJanqhxslH2bxM6duahNZ+HMpCLhBQGZkbX6xRf8x1Y2eJlgt2q3qo49Q==",
"requires": {
"sax": ">=0.6.0",
"xmlbuilder": "~9.0.1"
}
},
"xmlbuilder": {
"version": "9.0.7",
"resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-9.0.7.tgz",
"integrity": "sha1-Ey7mPS7FVlxVfiD0wi35rKaGsQ0="
}
}
}

View File

@@ -1,22 +0,0 @@
{
"name": "flameshot-storage-s3",
"author": {
"name": "Namecheap, Inc.",
"address": "https://www.namecheap.com/"
},
"private": true,
"version": "1.0.0",
"description": "AWS Lambda functions for the Flameshot S3 Storage.",
"main": "app.js",
"scripts": {
"start": "node testHarness.js",
"pack": "zip -r ../.infrastructure/lambda.zip ./",
"test": "echo \"Error: no test specified\" && exit 1"
},
"keywords": [],
"license": "GPL v3",
"dependencies": {
"aws-sdk": "^2.478.0",
"short-uuid": "^3.1.1"
}
}

View File

@@ -1,25 +0,0 @@
/*
Copyright 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved.
Permission is hereby granted, free of charge, to any person obtaining a copy of this
software and associated documentation files (the "Software"), to deal in the Software
without restriction, including without limitation the rights to use, copy, modify,
merge, publish, distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
// For local testing
const { handler } = require('./app')
const main = async () => {
await handler()
}
main()

View File

@@ -1,69 +0,0 @@
#include "imgs3settings.h"
#include <QDir>
#include <QFileInfo>
#include <QSettings>
ImgS3Settings::ImgS3Settings()
{
initSettings();
// get s3 credentials
m_settings->beginGroup("S3");
m_credsUrl = m_settings->value("S3_CREDS_URL").toString();
m_credsUrl =
m_credsUrl +
((m_credsUrl.length() > 0 && m_credsUrl[m_credsUrl.length() - 1] == '/')
? ""
: "/") +
S3_API_IMG_PATH;
m_xApiKey = m_settings->value("S3_X_API_KEY").toString();
m_url = m_settings->value("S3_URL").toString();
m_url =
m_url +
((m_url.length() > 0 && m_url[m_url.length() - 1] == '/') ? "" : "/");
m_settings->endGroup();
}
QSettings* ImgS3Settings::settings()
{
return m_settings;
}
void ImgS3Settings::initSettings()
{
// get s3 settings
QString configIniPath = QDir(QDir::currentPath()).filePath("config.ini");
if (!(QFileInfo::exists(configIniPath) &&
QFileInfo(configIniPath).isFile())) {
#if defined(Q_OS_LINUX) || defined(Q_OS_UNIX)
configIniPath = "/etc/flameshot/config.ini";
#elif defined(Q_OS_WIN)
// calculate workdir for flameshot on startup if is not set yet
QSettings bootUpSettings(
"HKEY_CURRENT_"
"USER\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Run",
QSettings::NativeFormat);
QFileInfo fi(bootUpSettings.value("Flameshot").toString());
configIniPath = QDir(fi.absolutePath()).filePath("config.ini");
#endif
}
m_settings = new QSettings(configIniPath, QSettings::IniFormat);
}
const QString& ImgS3Settings::credsUrl()
{
return m_credsUrl;
}
const QString& ImgS3Settings::xApiKey()
{
return m_xApiKey;
}
const QString& ImgS3Settings::url()
{
return m_url;
}

View File

@@ -1,30 +0,0 @@
#ifndef IMGS3SETTINGS_H
#define IMGS3SETTINGS_H
#define S3_API_IMG_PATH "v2/image/"
#include <QString>
class QSettings;
class ImgS3Settings
{
public:
ImgS3Settings();
const QString& credsUrl();
const QString& xApiKey();
const QString& url();
QSettings* settings();
private:
void initSettings();
// class members
QSettings* m_settings;
QString m_credsUrl;
QString m_xApiKey;
QString m_url;
};
#endif // IMGS3SETTINGS_H

View File

@@ -1,397 +0,0 @@
// Copyright(c) 2017-2019 Alejandro Sirgo Rica & Contributors
// 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 <http://www.gnu.org/licenses/>.
#include "imgs3uploader.h"
#include "imgs3settings.h"
#include "src/core/controller.h"
#include "src/utils/confighandler.h"
#include "src/utils/history.h"
#include "src/utils/systemnotification.h"
#include "src/widgets/imagelabel.h"
#include "src/widgets/loadspinner.h"
#include "src/widgets/notificationwidget.h"
#include <QApplication>
#include <QBuffer>
#include <QClipboard>
#include <QDir>
#include <QHttpMultiPart>
#include <QJsonDocument>
#include <QJsonObject>
#include <QLabel>
#include <QMessageBox>
#include <QMimeData>
#include <QNetworkAccessManager>
#include <QNetworkProxy>
#include <QNetworkReply>
#include <QNetworkRequest>
#include <QPushButton>
#include <QShortcut>
#include <QUrlQuery>
#include <QVBoxLayout>
ImgS3Uploader::ImgS3Uploader(const QPixmap& capture, QWidget* parent)
: ImgUploader(capture, parent)
{
init(tr("Upload image to S3"), tr("Uploading Image"));
}
ImgS3Uploader::ImgS3Uploader(QWidget* parent)
: ImgUploader(parent)
{
init(tr("Delete image from S3"), tr("Deleting image..."));
}
ImgS3Uploader::~ImgS3Uploader()
{
clearProxy();
}
void ImgS3Uploader::init(const QString& title, const QString& label)
{
m_proxy = nullptr;
m_NetworkAMUpload = nullptr;
m_NetworkAMGetCreds = nullptr;
m_NetworkAMRemove = nullptr;
resultStatus = false;
setWindowTitle(title);
setWindowIcon(QIcon(":img/app/flameshot.svg"));
}
QNetworkProxy* ImgS3Uploader::proxy()
{
if (m_proxy == nullptr) {
initProxy();
}
return m_proxy;
}
QNetworkProxy* ImgS3Uploader::initProxy()
{
// get s3 settings
ImgS3Settings imgS3Settings;
// get proxy settings from "config.ini" file
QSettings* settings = imgS3Settings.settings();
QString httpProxyHost = settings->value("HTTP_PROXY_HOST").toString();
if (httpProxyHost.length() > 0) {
m_proxy = new QNetworkProxy();
if (settings->contains("HTTP_PROXY_TYPE")) {
switch (settings->value("HTTP_PROXY_TYPE").toInt()) {
case 0:
m_proxy->setType(QNetworkProxy::DefaultProxy);
break;
case 1:
m_proxy->setType(QNetworkProxy::Socks5Proxy);
break;
case 2:
m_proxy->setType(QNetworkProxy::NoProxy);
break;
case 4:
m_proxy->setType(QNetworkProxy::HttpCachingProxy);
break;
case 5:
m_proxy->setType(QNetworkProxy::FtpCachingProxy);
break;
case 3:
default:
m_proxy->setType(QNetworkProxy::HttpProxy);
break;
}
}
m_proxy->setHostName(httpProxyHost);
int nProxyPort = 3128;
if (settings->contains("HTTP_PROXY_PORT")) {
nProxyPort = settings->value("HTTP_PROXY_PORT").toInt();
}
m_proxy->setPort(nProxyPort);
if (settings->contains("HTTP_PROXY_USER")) {
qDebug() << "Proxy user"
<< settings->value("HTTP_PROXY_PASSWORD").toString();
m_proxy->setUser(settings->value("HTTP_PROXY_USER").toString());
}
if (settings->contains("HTTP_PROXY_PASSWORD")) {
qDebug() << "Proxy password is not empty";
m_proxy->setPassword(
settings->value("HTTP_PROXY_PASSWORD").toString());
}
} else {
// Get proxy settings from OS settings
QNetworkProxyQuery q(QUrl(m_s3Settings.credsUrl().toUtf8()));
q.setQueryType(QNetworkProxyQuery::UrlRequest);
q.setProtocolTag("http");
QList<QNetworkProxy> proxies =
QNetworkProxyFactory::systemProxyForQuery(q);
if (proxies.size() > 0 && proxies[0].type() != QNetworkProxy::NoProxy) {
m_proxy = new QNetworkProxy();
m_proxy->setHostName(proxies[0].hostName());
m_proxy->setPort(proxies[0].port());
m_proxy->setType(proxies[0].type());
m_proxy->setUser(proxies[0].user());
m_proxy->setPassword(proxies[0].password());
}
}
#ifdef QT_DEBUG
if (m_proxy != nullptr) {
qDebug() << "Using proxy server";
qDebug() << "proxy host:" << m_proxy->hostName();
qDebug() << "proxy port:" << m_proxy->port();
qDebug() << "proxy type:" << m_proxy->type();
qDebug() << "proxy user:"
<< (m_proxy->user().length() > 0 ? m_proxy->user()
: "no user");
qDebug() << "proxy password:"
<< (m_proxy->password().length() > 0 ? "***" : "no password");
} else {
qDebug() << "No proxy";
}
#endif
return m_proxy;
}
void ImgS3Uploader::clearProxy()
{
if (m_proxy != nullptr) {
delete m_proxy;
m_proxy = nullptr;
}
}
void ImgS3Uploader::handleReplyUpload(QNetworkReply* reply)
{
hideSpinner();
m_storageImageName.clear();
if (reply->error() == QNetworkReply::NoError) {
// save history
QString imageName = imageUrl().toString();
int lastSlash = imageName.lastIndexOf("/");
if (lastSlash >= 0) {
imageName = imageName.mid(lastSlash + 1);
}
m_storageImageName = imageName;
// save image to history
History history;
imageName = history.packFileName(
SCREENSHOT_STORAGE_TYPE_S3, m_deleteToken, imageName);
history.save(pixmap(), imageName);
resultStatus = true;
// Copy url to clipboard if required
if (ConfigHandler().copyAndCloseAfterUploadEnabled()) {
QApplication::clipboard()->setText(imageUrl().toString());
SystemNotification().sendMessage(tr("URL copied to clipboard."));
Controller::getInstance()->updateRecentScreenshots();
close();
} else {
onUploadOk();
}
} else {
QString reason =
reply->attribute(QNetworkRequest::HttpReasonPhraseAttribute)
.toString();
setInfoLabelText(reply->errorString());
}
new QShortcut(Qt::Key_Escape, this, SLOT(close()));
}
void ImgS3Uploader::handleReplyDeleteResource(QNetworkReply* reply)
{
auto replyError = reply->error();
if (replyError == QNetworkReply::NoError) {
removeImagePreview();
} else {
hide();
// generate error message
QString message =
tr("Unable to remove screenshot from the remote storage.");
if (replyError == QNetworkReply::UnknownNetworkError) {
message += "\n" + tr("Network error");
} else if (replyError == QNetworkReply::UnknownServerError) {
message += "\n" + tr("Possibly it doesn't exist anymore");
}
message += "\n\n" + reply->errorString();
message +=
"\n\n" +
tr("Do you want to remove screenshot from local history anyway?");
if (QMessageBox::Yes ==
QMessageBox::question(NULL,
tr("Remove screenshot from history?"),
message,
QMessageBox::Yes | QMessageBox::No)) {
removeImagePreview();
}
}
close();
}
void ImgS3Uploader::handleReplyGetCreds(QNetworkReply* reply)
{
if (reply->error() == QNetworkReply::NoError) {
QJsonDocument response = QJsonDocument::fromJson(reply->readAll());
uploadToS3(response);
} else {
if (m_s3Settings.credsUrl().length() == 0) {
setInfoLabelText(
tr("S3 Creds URL is not found in your configuration file"));
} else {
setInfoLabelText(reply->errorString());
}
}
new QShortcut(Qt::Key_Escape, this, SLOT(close()));
}
void ImgS3Uploader::uploadToS3(QJsonDocument& response)
{
// set paramets from "fields"
QHttpMultiPart* multiPart =
new QHttpMultiPart(QHttpMultiPart::FormDataType);
// read JSON response
QJsonObject json = response.object();
QString resultUrl = json["resultURL"].toString();
QJsonObject formData = json["formData"].toObject();
QString url = formData["url"].toString();
m_deleteToken = json["deleteToken"].toString();
QJsonObject fields = formData["fields"].toObject();
foreach (auto key, fields.keys()) {
QString field = fields[key].toString();
QHttpPart part;
part.setHeader(QNetworkRequest::ContentDispositionHeader,
QVariant("form-data; name=\"" + key + "\""));
part.setBody(field.toLatin1());
multiPart->append(part);
}
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);
pixmap().save(&buffer, "PNG");
imagePart.setBody(byteArray);
multiPart->append(imagePart);
setImageUrl(QUrl(resultUrl));
QUrl qUrl(url);
QNetworkRequest request(qUrl);
// upload
m_NetworkAMUpload->post(request, multiPart);
}
void ImgS3Uploader::deleteResource(const QString& fileName,
const QString& deleteToken)
{
// read network settings on each call to simplify configuration management
// without restarting
clearProxy();
if (m_NetworkAMRemove != nullptr) {
delete m_NetworkAMRemove;
m_NetworkAMRemove = nullptr;
}
m_NetworkAMRemove = new QNetworkAccessManager(this);
connect(m_NetworkAMRemove,
&QNetworkAccessManager::finished,
this,
&ImgS3Uploader::handleReplyDeleteResource);
if (proxy() != nullptr) {
m_NetworkAMRemove->setProxy(*proxy());
}
QNetworkRequest request;
m_storageImageName = fileName;
m_deleteToken = deleteToken;
request.setUrl(m_s3Settings.credsUrl().toUtf8() + fileName);
request.setRawHeader("X-API-Key", m_s3Settings.xApiKey().toLatin1());
request.setRawHeader("Authorization", "Bearer " + deleteToken.toLatin1());
m_NetworkAMRemove->deleteResource(request);
}
void ImgS3Uploader::upload()
{
m_deleteToken.clear();
m_storageImageName.clear();
// read network settings on each call to simplify configuration management
// without restarting init creds and upload network access managers
clearProxy();
if (m_NetworkAMGetCreds != nullptr) {
delete m_NetworkAMGetCreds;
m_NetworkAMGetCreds = nullptr;
}
m_NetworkAMGetCreds = new QNetworkAccessManager(this);
connect(m_NetworkAMGetCreds,
&QNetworkAccessManager::finished,
this,
&ImgS3Uploader::handleReplyGetCreds);
if (m_NetworkAMUpload != nullptr) {
delete m_NetworkAMUpload;
m_NetworkAMUpload = nullptr;
}
m_NetworkAMUpload = new QNetworkAccessManager(this);
connect(m_NetworkAMUpload,
&QNetworkAccessManager::finished,
this,
&ImgS3Uploader::handleReplyUpload);
if (proxy() != nullptr) {
m_NetworkAMGetCreds->setProxy(*proxy());
m_NetworkAMUpload->setProxy(*proxy());
}
// get creads
QUrl creds(m_s3Settings.credsUrl());
QNetworkRequest requestCreds(creds);
if (m_s3Settings.xApiKey().length() > 0) {
requestCreds.setRawHeader(
QByteArray("X-API-Key"),
QByteArray(m_s3Settings.xApiKey().toLocal8Bit()));
}
m_NetworkAMGetCreds->get(requestCreds);
}
void ImgS3Uploader::removeImagePreview()
{
// remove local file
History history;
QString packedFileName = history.packFileName(
SCREENSHOT_STORAGE_TYPE_S3, m_deleteToken, m_storageImageName);
QString fullFileName = history.path() + packedFileName;
QFile file(fullFileName);
if (file.exists()) {
file.remove();
}
m_deleteToken.clear();
m_storageImageName.clear();
resultStatus = true;
}

View File

@@ -1,70 +0,0 @@
// 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 <http://www.gnu.org/licenses/>.
#pragma once
#define S3_API_IMG_PATH "v2/image/"
#include "../imguploader.h"
#include "imgs3settings.h"
#include <QUrl>
#include <QWidget>
class QNetworkReply;
class QNetworkProxy;
class QNetworkAccessManager;
class QHBoxLayout;
class QVBoxLayout;
class QLabel;
class QPushButton;
class QUrl;
class NotificationWidget;
class ImageLabel;
class ImgS3Uploader : public ImgUploader
{
Q_OBJECT
public:
explicit ImgS3Uploader(const QPixmap& capture, QWidget* parent = nullptr);
explicit ImgS3Uploader(QWidget* parent = nullptr);
~ImgS3Uploader();
void upload();
void deleteResource(const QString&, const QString&);
private slots:
void handleReplyUpload(QNetworkReply* reply);
void handleReplyGetCreds(QNetworkReply* reply);
void handleReplyDeleteResource(QNetworkReply* reply);
private:
void init(const QString& title, const QString& label);
void uploadToS3(QJsonDocument& response);
void removeImagePreview();
QNetworkProxy* initProxy();
void clearProxy();
QNetworkProxy* proxy();
// class members
private:
ImgS3Settings m_s3Settings;
QNetworkProxy* m_proxy;
QNetworkAccessManager* m_NetworkAMUpload;
QNetworkAccessManager* m_NetworkAMGetCreds;
QNetworkAccessManager* m_NetworkAMRemove;
};

View File

@@ -1,41 +0,0 @@
// 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 <http://www.gnu.org/licenses/>.
#include "imgs3uploadertool.h"
#include "imgs3uploader.h"
#include <QPainter>
ImgS3UploaderTool::ImgS3UploaderTool(QObject* parent)
: ImgUploaderTool(parent)
{}
QString ImgS3UploaderTool::description() const
{
return tr("Upload the selection to S3 bucket");
}
QWidget* ImgS3UploaderTool::widget()
{
ImgS3Uploader* p = new ImgS3Uploader(capture());
p->upload();
return p;
}
CaptureTool* ImgS3UploaderTool::copy(QObject* parent)
{
return new ImgS3UploaderTool(parent);
}

View File

@@ -1,33 +0,0 @@
// 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 <http://www.gnu.org/licenses/>.
#pragma once
#include "src/tools/storage/imguploadertool.h"
class ImgS3UploaderTool : public ImgUploaderTool
{
Q_OBJECT
public:
ImgS3UploaderTool(QObject* parent = nullptr);
QString description() const override;
QWidget* widget() override;
CaptureTool* copy(QObject* parent = nullptr) override;
};

View File

@@ -1,56 +0,0 @@
#include "storagemanager.h"
#include "imguploader.h"
#include "imgur/imguruploadertool.h"
#include "s3/imgs3settings.h"
#include "s3/imgs3uploadertool.h"
#include "src/tools/capturetool.h"
#include <QSettings>
StorageManager::StorageManager() {}
CaptureTool* StorageManager::imgUploaderTool(const QString& imgUploaderType,
QObject* parent)
{
if (imgUploaderType == SCREENSHOT_STORAGE_TYPE_S3) {
return new ImgS3UploaderTool(parent);
} else if (imgUploaderType == SCREENSHOT_STORAGE_TYPE_IMGUR) {
return new ImgurUploaderTool(parent);
}
return nullptr;
}
const QString& StorageManager::storageUrl(const QString& imgUploaderType)
{
if (imgUploaderType == SCREENSHOT_STORAGE_TYPE_S3) {
ImgS3Settings s3Settings;
m_qstr = s3Settings.url();
} else if (imgUploaderType == SCREENSHOT_STORAGE_TYPE_IMGUR) {
m_qstr = "https://i.imgur.com/";
}
return m_qstr;
}
const QString& StorageManager::storageDefault()
{
ImgS3Settings imgS3Settings;
if (!imgS3Settings.xApiKey().isEmpty()) {
m_qstr = SCREENSHOT_STORAGE_TYPE_S3;
} else {
m_qstr = SCREENSHOT_STORAGE_TYPE_IMGUR;
}
return m_qstr;
}
bool StorageManager::storageLocked()
{
// TODO - move this to some common config file, not a storage specific
// configuration file
bool res = false;
ImgS3Settings imgS3Settings;
if (imgS3Settings.settings()->contains("STORAGE_LOCK")) {
res = imgS3Settings.settings()
->value(QStringLiteral("STORAGE_LOCK"))
.toBool();
}
return res;
}

View File

@@ -1,27 +0,0 @@
#ifndef STORAGEMANAGER_H
#define STORAGEMANAGER_H
#include <QPixmap>
#include <QString>
class QObject;
class ImgUploader;
class CaptureTool;
class StorageManager
{
public:
explicit StorageManager();
CaptureTool* imgUploaderTool(const QString& imgUploaderType,
QObject* parent = nullptr);
const QString& storageUrl(const QString& imgUploaderType);
const QString& storageDefault();
bool storageLocked();
private:
// class members
QString m_qstr;
};
#endif // STORAGEMANAGER_H

View File

@@ -22,6 +22,7 @@
#include "copy/copytool.h"
#include "exit/exittool.h"
#include "launcher/applaunchertool.h"
#include "imgur/imguruploadertool.h"
#include "line/linetool.h"
#include "marker/markertool.h"
#include "move/movetool.h"
@@ -34,7 +35,6 @@
#include "selection/selectiontool.h"
#include "sizeindicator/sizeindicatortool.h"
#include "src/utils/confighandler.h"
#include "storage/storagemanager.h"
#include "text/texttool.h"
#include "undo/undotool.h"
@@ -45,7 +45,6 @@ ToolFactory::ToolFactory(QObject* parent)
CaptureTool* ToolFactory::CreateTool(CaptureToolButton::ButtonType t,
QObject* parent)
{
StorageManager storageManager;
CaptureTool* tool;
switch (t) {
case CaptureToolButton::TYPE_ARROW:
@@ -61,8 +60,7 @@ CaptureTool* ToolFactory::CreateTool(CaptureToolButton::ButtonType t,
tool = new ExitTool(parent);
break;
case CaptureToolButton::TYPE_IMAGEUPLOADER:
tool = storageManager.imgUploaderTool(
ConfigHandler().uploadStorage(), parent);
tool = new ImgurUploaderTool(parent);
break;
case CaptureToolButton::TYPE_DRAWER:
tool = new LineTool(parent);

View File

@@ -17,7 +17,6 @@
#include "confighandler.h"
#include "src/tools/capturetool.h"
#include "src/tools/storage/storagemanager.h"
#include "src/utils/configshortcuts.h"
#include <QCoreApplication>
#include <QDir>
@@ -87,11 +86,8 @@ QVector<QColor> ConfigHandler::getUserColors()
{
QVector<QColor> colors;
const QVector<QColor>& defaultColors = {
Qt::white, Qt::red, Qt::green, Qt::blue,
Qt::black, Qt::darkRed, Qt::darkGreen, Qt::darkBlue,
Qt::darkGray, Qt::cyan, Qt::magenta, Qt::yellow,
Qt::lightGray, Qt::darkCyan, Qt::darkMagenta, Qt::darkYellow,
QColor()
Qt::darkRed, Qt::red, Qt::yellow, Qt::green, Qt::darkGreen,
Qt::cyan, Qt::blue, Qt::magenta, Qt::darkMagenta, QColor()
};
if (m_settings.contains(QStringLiteral("userColors"))) {
@@ -456,34 +452,6 @@ void ConfigHandler::setCopyPathAfterSaveEnabled(const bool value)
m_settings.setValue(QStringLiteral("copyPathAfterSave"), value);
}
void ConfigHandler::setUploadStorage(const QString& uploadStorage)
{
StorageManager storageManager;
if (storageManager.storageLocked()) {
m_settings.setValue(QStringLiteral("uploadStorage"),
storageManager.storageDefault());
} else {
m_settings.setValue(QStringLiteral("uploadStorage"), uploadStorage);
}
}
const QString& ConfigHandler::uploadStorage()
{
StorageManager storageManager;
// check for storage lock
if (storageManager.storageLocked()) {
setUploadStorage(storageManager.storageDefault());
}
// get storage
m_strRes = m_settings.value(QStringLiteral("uploadStorage")).toString();
if (m_strRes.isEmpty()) {
StorageManager storageManager;
m_strRes = storageManager.storageDefault();
setUploadStorage(m_strRes);
}
return m_strRes;
}
QString ConfigHandler::saveAfterCopyPathValue()
{

View File

@@ -93,9 +93,6 @@ public:
bool copyPathAfterSaveEnabled();
void setCopyPathAfterSaveEnabled(const bool);
void setUploadStorage(const QString&);
const QString& uploadStorage();
void setDefaults();
void setAllTheButtons();

View File

@@ -25,7 +25,6 @@
#include "capturewidget.h"
#include "src/core/controller.h"
#include "src/tools/storage/storagemanager.h"
#include "src/tools/toolfactory.h"
#include "src/utils/colorutils.h"
#include "src/utils/screengrabber.h"
@@ -1094,16 +1093,6 @@ void CaptureWidget::childLeave()
update();
}
void CaptureWidget::uploadScreenshot()
{
StorageManager storageManager;
m_activeTool =
storageManager.imgUploaderTool(ConfigHandler().uploadStorage());
m_activeTool->setCapture(pixmap());
handleButtonSignal(CaptureTool::REQ_ADD_EXTERNAL_WIDGETS);
close();
}
void CaptureWidget::copyScreenshot()
{
m_captureDone = true;

View File

@@ -73,7 +73,6 @@ private slots:
// TODO replace with tools
void copyScreenshot();
void saveScreenshot();
void uploadScreenshot();
void undo();
void redo();
void togglePanel();

View File

@@ -1,7 +1,4 @@
#include "historywidget.h"
#include "src/tools/storage/imguploader.h"
#include "src/tools/storage/s3/imgs3uploader.h"
#include "src/tools/storage/storagemanager.h"
#include "src/utils/history.h"
#include "src/widgets/notificationwidget.h"
#include <QApplication>
@@ -99,9 +96,6 @@ void HistoryWidget::addLine(const QString& path, const QString& fileName)
QString url;
StorageManager storageManager;
url = storageManager.storageUrl(unpackFileName.type) + unpackFileName.file;
// load pixmap
QPixmap pixmap;
pixmap.load(fullFileName, "png");
@@ -155,24 +149,11 @@ void HistoryWidget::addLine(const QString& path, const QString& fileName)
buttonDelete->setIcon(QIcon(":/img/material/black/delete.svg"));
buttonDelete->setMinimumHeight(HISTORYPIXMAP_MAX_PREVIEW_HEIGHT);
connect(buttonDelete, &QPushButton::clicked, this, [=]() {
// TODO - remove dependency injection (s3 & imgur)
if (unpackFileName.type.compare(SCREENSHOT_STORAGE_TYPE_S3) == 0) {
if (unpackFileName.token.length() > 0) {
removeItem(phbl, unpackFileName.file, unpackFileName.token);
} else {
// for compatibility with previous versions and to be able to
// remove previous screenshots
removeCacheFile(fullFileName);
removeLayoutItem(phbl);
}
} else if (unpackFileName.type.compare(SCREENSHOT_STORAGE_TYPE_IMGUR) ==
0) {
QDesktopServices::openUrl(
QUrl(QStringLiteral("https://imgur.com/delete/%1")
.arg(unpackFileName.token)));
removeCacheFile(fullFileName);
removeLayoutItem(phbl);
}
QDesktopServices::openUrl(
QUrl(QStringLiteral("https://imgur.com/delete/%1")
.arg(unpackFileName.token)));
removeCacheFile(fullFileName);
removeLayoutItem(phbl);
});
// layout
@@ -196,17 +177,17 @@ void HistoryWidget::removeItem(QLayout* pl,
const QString& fileName,
const QString& deleteToken)
{
hide();
ImgS3Uploader* imgUploader = new ImgS3Uploader();
imgUploader->show();
imgUploader->deleteResource(fileName, deleteToken);
connect(imgUploader, &QWidget::destroyed, this, [=]() {
if (imgUploader->resultStatus) {
removeLayoutItem(pl);
}
imgUploader->deleteLater();
show();
});
/* hide();
ImgS3Uploader* imgUploader = new ImgS3Uploader();
imgUploader->show();
imgUploader->deleteResource(fileName, deleteToken);
connect(imgUploader, &QWidget::destroyed, this, [=]() {
if (imgUploader->resultStatus) {
removeLayoutItem(pl);
}
imgUploader->deleteLater();
show();
});*/
}
void HistoryWidget::removeLayoutItem(QLayout* pl)