Fixes and more changes Pajlada requested :)

- get rid of `getImageFileFormat`, now uses QMimeDatabase
 - now uses a `QMutex` to be thread safe,
 - uploading two things at the same time is now impossible
This commit is contained in:
Mm2PL 2020-02-08 16:26:32 +01:00
parent 553e8f2f7b
commit d53bfbfdf2
No known key found for this signature in database
GPG key ID: 1C400DA5602DE62E

View file

@ -4,26 +4,16 @@
#include "common/NetworkRequest.hpp" #include "common/NetworkRequest.hpp"
#include "providers/twitch/TwitchMessageBuilder.hpp" #include "providers/twitch/TwitchMessageBuilder.hpp"
#include <QBuffer>
#include <QHttpMultiPart> #include <QHttpMultiPart>
#include <QMimeDatabase>
#include <QMutex>
#define UPLOAD_DELAY 2000 #define UPLOAD_DELAY 2000
// Delay between uploads in milliseconds // Delay between uploads in milliseconds
namespace { namespace {
QString getImageFileFormat(const QString &path)
{
static QStringList listOfImageFormats = {".png", ".jpg", ".jpeg"};
for (const QString &format : listOfImageFormats)
{
if (path.endsWith(format, Qt::CaseInsensitive))
{
return format.mid(1);
}
}
return QString();
}
boost::optional<QByteArray> convertToPng(QImage image) boost::optional<QByteArray> convertToPng(QImage image)
{ {
QByteArray imageData; QByteArray imageData;
@ -43,7 +33,7 @@ boost::optional<QByteArray> convertToPng(QImage image)
namespace chatterino { namespace chatterino {
// These variables are only used from the main thread. // These variables are only used from the main thread.
bool isUploading = false; auto uploadMutex = QMutex();
std::queue<RawImageData> uploadQueue; std::queue<RawImageData> uploadQueue;
void uploadImageToNuuls(RawImageData imageData, ChannelPtr channel, void uploadImageToNuuls(RawImageData imageData, ChannelPtr channel,
@ -73,11 +63,11 @@ void uploadImageToNuuls(RawImageData imageData, ChannelPtr channel,
.multiPart(payload) .multiPart(payload)
.onSuccess([&textEdit, channel](NetworkResult result) -> Outcome { .onSuccess([&textEdit, channel](NetworkResult result) -> Outcome {
textEdit.insertPlainText(result.getData() + QString(" ")); textEdit.insertPlainText(result.getData() + QString(" "));
isUploading = false;
if (uploadQueue.empty()) if (uploadQueue.empty())
{ {
channel->addMessage(makeSystemMessage( channel->addMessage(makeSystemMessage(
QString("Your image has been uploaded."))); QString("Your image has been uploaded.")));
uploadMutex.unlock();
} }
else else
{ {
@ -101,7 +91,7 @@ void uploadImageToNuuls(RawImageData imageData, ChannelPtr channel,
channel->addMessage(makeSystemMessage( channel->addMessage(makeSystemMessage(
QString("An error happened while uploading your image: %1") QString("An error happened while uploading your image: %1")
.arg(result.status()))); .arg(result.status())));
isUploading = false; uploadMutex.unlock();
return true; return true;
}) })
.execute(); .execute();
@ -110,15 +100,13 @@ void uploadImageToNuuls(RawImageData imageData, ChannelPtr channel,
void upload(const QMimeData *source, ChannelPtr channel, void upload(const QMimeData *source, ChannelPtr channel,
ResizingTextEdit &outputTextEdit) ResizingTextEdit &outputTextEdit)
{ {
// There's no need to thread proof this function. It is called only from the main thread. if (!uploadMutex.tryLock())
if (isUploading)
{ {
channel->addMessage(makeSystemMessage( channel->addMessage(makeSystemMessage(
QString("Please wait until the upload finishes."))); QString("Please wait until the upload finishes.")));
return; return;
} }
isUploading = true;
channel->addMessage(makeSystemMessage(QString("Started upload..."))); channel->addMessage(makeSystemMessage(QString("Started upload...")));
if (source->hasFormat("image/png")) if (source->hasFormat("image/png"))
@ -138,12 +126,15 @@ void upload(const QMimeData *source, ChannelPtr channel,
} }
else if (source->hasUrls()) else if (source->hasUrls())
{ {
auto mimeDb = QMimeDatabase();
// This path gets chosen when files are copied from a file manager, like explorer.exe, caja. // This path gets chosen when files are copied from a file manager, like explorer.exe, caja.
// Each entry in source->urls() is a QUrl pointing to a file that was copied. // Each entry in source->urls() is a QUrl pointing to a file that was copied.
for (const QUrl &path : source->urls()) for (const QUrl &path : source->urls())
{ {
QString localPath = path.toLocalFile(); QString localPath = path.toLocalFile();
if (!getImageFileFormat(localPath).isEmpty()) QMimeType mime = mimeDb.mimeTypeForUrl(path);
qDebug() << mime.name();
if (mime.name().startsWith("image") && !mime.inherits("image/gif"))
{ {
channel->addMessage(makeSystemMessage( channel->addMessage(makeSystemMessage(
QString("Uploading image: %1").arg(localPath))); QString("Uploading image: %1").arg(localPath)));
@ -152,7 +143,7 @@ void upload(const QMimeData *source, ChannelPtr channel,
{ {
channel->addMessage( channel->addMessage(
makeSystemMessage(QString("Couldn't load image :("))); makeSystemMessage(QString("Couldn't load image :(")));
isUploading = false; uploadMutex.unlock();
return; return;
} }
@ -170,7 +161,7 @@ void upload(const QMimeData *source, ChannelPtr channel,
.arg(localPath))); .arg(localPath)));
} }
} }
else if (localPath.endsWith(".gif")) else if (mime.inherits("image/gif"))
{ {
channel->addMessage(makeSystemMessage( channel->addMessage(makeSystemMessage(
QString("Uploading GIF: %1").arg(localPath))); QString("Uploading GIF: %1").arg(localPath)));
@ -180,7 +171,7 @@ void upload(const QMimeData *source, ChannelPtr channel,
{ {
channel->addMessage( channel->addMessage(
makeSystemMessage(QString("Failed to open file. :("))); makeSystemMessage(QString("Failed to open file. :(")));
isUploading = false; uploadMutex.unlock();
return; return;
} }
RawImageData data = {file.readAll(), "gif"}; RawImageData data = {file.readAll(), "gif"};
@ -193,7 +184,8 @@ void upload(const QMimeData *source, ChannelPtr channel,
channel->addMessage(makeSystemMessage( channel->addMessage(makeSystemMessage(
QString("Cannot upload file: %1, not an image") QString("Cannot upload file: %1, not an image")
.arg(localPath))); .arg(localPath)));
isUploading = false; uploadMutex.unlock();
return;
} }
} }
if (!uploadQueue.empty()) if (!uploadQueue.empty())
@ -215,7 +207,7 @@ void upload(const QMimeData *source, ChannelPtr channel,
{ {
channel->addMessage(makeSystemMessage( channel->addMessage(makeSystemMessage(
QString("Cannot upload file, failed to convert to png."))); QString("Cannot upload file, failed to convert to png.")));
isUploading = false; uploadMutex.unlock();
} }
} }
} }