mirror of
https://github.com/Chatterino/chatterino2.git
synced 2024-11-13 19:49:51 +01:00
Use pajlada::Settings for uploaded images (includes migration)
This commit is contained in:
parent
6d02bb7304
commit
d7a888d651
|
@ -9,16 +9,21 @@
|
|||
#include "singletons/Paths.hpp"
|
||||
#include "singletons/Settings.hpp"
|
||||
#include "util/CombinePath.hpp"
|
||||
#include "util/RapidjsonHelpers.hpp"
|
||||
#include "widgets/helper/ResizingTextEdit.hpp"
|
||||
|
||||
#include <QBuffer>
|
||||
#include <QHttpMultiPart>
|
||||
#include <QJsonArray>
|
||||
#include <QJsonDocument>
|
||||
#include <qloggingcategory.h>
|
||||
#include <QMimeDatabase>
|
||||
#include <QMutex>
|
||||
#include <QPointer>
|
||||
#include <QSaveFile>
|
||||
#include <rapidjson/document.h>
|
||||
|
||||
#include <memory>
|
||||
|
||||
#define UPLOAD_DELAY 2000
|
||||
// Delay between uploads in milliseconds
|
||||
|
@ -48,50 +53,15 @@ void ImageUploader::logToFile(const QString &originalFilePath,
|
|||
const QString &imageLink,
|
||||
const QString &deletionLink, ChannelPtr channel)
|
||||
{
|
||||
const QString logFileName =
|
||||
combinePath((getSettings()->logPath.getValue().isEmpty()
|
||||
? getPaths()->messageLogDirectory
|
||||
: getSettings()->logPath),
|
||||
"ImageUploader.json");
|
||||
|
||||
//reading existing logs
|
||||
QFile logReadFile(logFileName);
|
||||
bool isLogFileOkay =
|
||||
logReadFile.open(QIODevice::ReadWrite | QIODevice::Text);
|
||||
if (!isLogFileOkay)
|
||||
{
|
||||
channel->addMessage(makeSystemMessage(
|
||||
QString("Failed to open log file with links at ") + logFileName));
|
||||
return;
|
||||
}
|
||||
auto logs = logReadFile.readAll();
|
||||
if (logs.isEmpty())
|
||||
{
|
||||
logs = QJsonDocument(QJsonArray()).toJson();
|
||||
}
|
||||
logReadFile.close();
|
||||
|
||||
//writing new data to logs
|
||||
QJsonObject newLogEntry;
|
||||
newLogEntry["channelName"] = channel->getName();
|
||||
newLogEntry["deletionLink"] =
|
||||
deletionLink.isEmpty() ? QJsonValue(QJsonValue::Null) : deletionLink;
|
||||
newLogEntry["imageLink"] = imageLink;
|
||||
newLogEntry["localPath"] = originalFilePath.isEmpty()
|
||||
? QJsonValue(QJsonValue::Null)
|
||||
: originalFilePath;
|
||||
newLogEntry["timestamp"] = QDateTime::currentSecsSinceEpoch();
|
||||
// channel name
|
||||
// deletion link (can be empty)
|
||||
// image link
|
||||
// local path to an image (can be empty)
|
||||
// timestamp
|
||||
QSaveFile logSaveFile(logFileName);
|
||||
logSaveFile.open(QIODevice::WriteOnly | QIODevice::Text);
|
||||
QJsonArray entries = QJsonDocument::fromJson(logs).array();
|
||||
entries.push_back(newLogEntry);
|
||||
logSaveFile.write(QJsonDocument(entries).toJson());
|
||||
logSaveFile.commit();
|
||||
this->imageLogSetting_->push_back(UploadedImage{
|
||||
.channelName = channel->getName(),
|
||||
.deletionLink = deletionLink,
|
||||
.imageLink = imageLink,
|
||||
.localPath = originalFilePath,
|
||||
.timestamp = QDateTime::currentSecsSinceEpoch(),
|
||||
});
|
||||
qCDebug(chatterinoCommon) << "Saving ImageUploader.json";
|
||||
this->sm_->save();
|
||||
}
|
||||
|
||||
// extracting link to either image or its deletion from response body
|
||||
|
@ -121,6 +91,59 @@ QString getLinkFromResponse(NetworkResult response, QString pattern)
|
|||
|
||||
void ImageUploader::save()
|
||||
{
|
||||
this->sm_->save();
|
||||
}
|
||||
|
||||
void ImageUploader::initialize(Settings &settings, Paths &paths)
|
||||
{
|
||||
auto logPath = (getSettings()->logPath.getValue().isEmpty()
|
||||
? getPaths()->messageLogDirectory
|
||||
: getSettings()->logPath);
|
||||
const QString oldLogName = combinePath(logPath, "ImageUploader.json");
|
||||
|
||||
// read/write new one
|
||||
const QString path = combinePath(logPath, "ImageUploader2.json");
|
||||
this->sm_ = std::make_shared<pajlada::Settings::SettingManager>();
|
||||
this->sm_->setPath(qPrintable(path));
|
||||
this->sm_->setBackupEnabled(true);
|
||||
this->sm_->setBackupSlots(9);
|
||||
|
||||
this->imageLogSetting_ = std::make_unique<
|
||||
pajlada::Settings::Setting<std::vector<UploadedImage>>>(
|
||||
"/uploadedImages", this->sm_);
|
||||
|
||||
// try to read old log
|
||||
QFile oldLogFile(oldLogName);
|
||||
bool isOldLogFileOkay =
|
||||
oldLogFile.open(QIODevice::ReadOnly | QIODevice::Text);
|
||||
if (isOldLogFileOkay)
|
||||
{
|
||||
auto data = oldLogFile.readAll();
|
||||
rapidjson::Document doc;
|
||||
doc.Parse(data.data(), data.size());
|
||||
if (doc.HasParseError())
|
||||
{
|
||||
qCWarning(chatterinoCommon) << "Unable to read ImageUploader.json";
|
||||
return;
|
||||
}
|
||||
std::vector<UploadedImage> temporary;
|
||||
if (!doc.IsArray())
|
||||
{
|
||||
qCWarning(chatterinoCommon)
|
||||
<< "Unable to parse ImageUploader.json: not an array";
|
||||
return;
|
||||
}
|
||||
if (!rj::getSafe(doc, temporary))
|
||||
{
|
||||
qCWarning(chatterinoCommon)
|
||||
<< "Unable to parse ImageUploader.json: getSafe failed";
|
||||
return;
|
||||
}
|
||||
this->imageLogSetting_->setValue(temporary);
|
||||
oldLogFile.close();
|
||||
oldLogFile.rename(combinePath(logPath, "ImageUploader.old.json"));
|
||||
this->sm_->save();
|
||||
}
|
||||
}
|
||||
|
||||
void ImageUploader::sendImageUploadRequest(RawImageData imageData,
|
||||
|
|
|
@ -1,11 +1,16 @@
|
|||
#pragma once
|
||||
|
||||
#include "common/Singleton.hpp"
|
||||
#include "pajlada/settings/setting.hpp"
|
||||
#include "pajlada/settings/settingmanager.hpp"
|
||||
#include "util/RapidjsonHelpers.hpp"
|
||||
|
||||
#include <QMimeData>
|
||||
#include <QMutex>
|
||||
#include <QString>
|
||||
#include <Qt>
|
||||
|
||||
#include <cstdint>
|
||||
#include <memory>
|
||||
#include <queue>
|
||||
|
||||
|
@ -22,12 +27,21 @@ struct RawImageData {
|
|||
QString filePath;
|
||||
};
|
||||
|
||||
struct UploadedImage {
|
||||
QString channelName;
|
||||
QString deletionLink;
|
||||
QString imageLink;
|
||||
QString localPath;
|
||||
int64_t timestamp{};
|
||||
};
|
||||
|
||||
class ImageUploader final : public Singleton
|
||||
{
|
||||
public:
|
||||
void save() override;
|
||||
void upload(const QMimeData *source, ChannelPtr channel,
|
||||
QPointer<ResizingTextEdit> outputTextEdit);
|
||||
void initialize(Settings &settings, Paths &paths) override;
|
||||
|
||||
private:
|
||||
void sendImageUploadRequest(RawImageData imageData, ChannelPtr channel,
|
||||
|
@ -45,5 +59,80 @@ private:
|
|||
// These variables are only used from the main thread.
|
||||
QMutex uploadMutex_;
|
||||
std::queue<RawImageData> uploadQueue_;
|
||||
|
||||
std::shared_ptr<pajlada::Settings::SettingManager> sm_;
|
||||
std::unique_ptr<pajlada::Settings::Setting<std::vector<UploadedImage>>>
|
||||
imageLogSetting_;
|
||||
};
|
||||
} // namespace chatterino
|
||||
//
|
||||
namespace pajlada {
|
||||
template <>
|
||||
struct Serialize<chatterino::UploadedImage> {
|
||||
static rapidjson::Value get(const chatterino::UploadedImage &value,
|
||||
rapidjson::Document::AllocatorType &a)
|
||||
{
|
||||
rapidjson::Value ret(rapidjson::kObjectType);
|
||||
|
||||
chatterino::rj::set(ret, "channelName", value.channelName, a);
|
||||
chatterino::rj::set(ret, "imageLink", value.imageLink, a);
|
||||
chatterino::rj::set(ret, "timestamp", value.timestamp, a);
|
||||
chatterino::rj::set(ret, "localPath", value.localPath, a);
|
||||
chatterino::rj::set(ret, "deletionLink", value.deletionLink, a);
|
||||
|
||||
return ret;
|
||||
}
|
||||
};
|
||||
|
||||
template <>
|
||||
struct Deserialize<chatterino::UploadedImage> {
|
||||
static chatterino::UploadedImage get(const rapidjson::Value &value,
|
||||
bool *error = nullptr)
|
||||
{
|
||||
chatterino::UploadedImage img;
|
||||
|
||||
if (!value.IsObject())
|
||||
{
|
||||
PAJLADA_REPORT_ERROR(error);
|
||||
return img;
|
||||
}
|
||||
|
||||
if (value["localPath"].IsNull())
|
||||
{
|
||||
img.localPath = QString();
|
||||
}
|
||||
else if (!chatterino::rj::getSafe(value, "localPath", img.localPath))
|
||||
{
|
||||
PAJLADA_REPORT_ERROR(error);
|
||||
return img;
|
||||
}
|
||||
if (!chatterino::rj::getSafe(value, "imageLink", img.imageLink))
|
||||
{
|
||||
PAJLADA_REPORT_ERROR(error);
|
||||
return img;
|
||||
}
|
||||
if (value["deletionLink"].IsNull())
|
||||
{
|
||||
img.deletionLink = QString();
|
||||
}
|
||||
else if (!chatterino::rj::getSafe(value, "deletionLink",
|
||||
img.deletionLink))
|
||||
{
|
||||
PAJLADA_REPORT_ERROR(error);
|
||||
return img;
|
||||
}
|
||||
if (!chatterino::rj::getSafe(value, "channelName", img.channelName))
|
||||
{
|
||||
PAJLADA_REPORT_ERROR(error);
|
||||
return img;
|
||||
}
|
||||
if (!chatterino::rj::getSafe(value, "timestamp", img.timestamp))
|
||||
{
|
||||
PAJLADA_REPORT_ERROR(error);
|
||||
return img;
|
||||
}
|
||||
|
||||
return img;
|
||||
}
|
||||
};
|
||||
} // namespace pajlada
|
||||
|
|
Loading…
Reference in a new issue