Skip to content

Commit

Permalink
FileContentBase::commonInfo()
Browse files Browse the repository at this point in the history
Fixes dealing with common attributes being a problem, described in
#812 (comment)
  • Loading branch information
KitsuneRal committed Oct 22, 2024
1 parent 05b6e31 commit 16ceb7a
Show file tree
Hide file tree
Showing 3 changed files with 51 additions and 45 deletions.
45 changes: 25 additions & 20 deletions Quotient/events/eventcontent.h
Original file line number Diff line number Diff line change
Expand Up @@ -151,8 +151,27 @@ struct QUOTIENT_API Thumbnail : public ImageInfo {
//! The base for all file-based content classes
class QUOTIENT_API FileContentBase : public Base {
public:
using Base::Base;
FileContentBase(const QJsonObject& contentJson = {})
: Base(contentJson), thumbnail(contentJson[InfoKey].toObject())
{}
virtual QUrl url() const = 0;
virtual FileInfo commonInfo() const = 0;

Thumbnail thumbnail;

protected:
virtual QJsonObject makeInfoJson() const = 0;

void fillJson(QJsonObject& json) const override
{
const auto fileInfo = commonInfo();
Quotient::fillJson(json, { "url"_L1, "file"_L1 }, fileInfo.source);
addParam<IfNotEmpty>(json, "filename"_L1, fileInfo.originalName);
auto infoJson = makeInfoJson();
if (thumbnail.isValid())
thumbnail.dumpTo(infoJson);
json.insert(InfoKey, infoJson);
}
};

//! \brief Rich text content for m.text, m.emote, m.notice
Expand Down Expand Up @@ -214,7 +233,6 @@ class UrlBasedContent : public FileContentBase, public InfoT {
: FileContentBase(json)
, InfoT(fileSourceInfoFromJson(json, { "url"_L1, "file"_L1 }), json[InfoKey].toObject(),
json["filename"_L1].toString())
, thumbnail(FileInfo::originalInfoJson)
{
// Two small hacks on originalJson to expose mediaIds to QML
originalJson.insert("mediaId"_L1, InfoT::mediaId());
Expand All @@ -223,25 +241,10 @@ class UrlBasedContent : public FileContentBase, public InfoT {

QMimeType type() const override { return InfoT::mimeType; }
QUrl url() const override { return InfoT::url(); }

public:
Thumbnail thumbnail;
FileInfo commonInfo() const override { return SLICE(*this, FileInfo); }

protected:
virtual void fillInfoJson(QJsonObject& infoJson [[maybe_unused]]) const
{}

void fillJson(QJsonObject& json) const override
{
Quotient::fillJson(json, { "url"_L1, "file"_L1 }, InfoT::source);
if (!InfoT::originalName.isEmpty())
json.insert("filename"_L1, InfoT::originalName);
auto infoJson = toInfoJson(*this);
if (thumbnail.isValid())
thumbnail.dumpTo(infoJson);
fillInfoJson(infoJson);
json.insert(InfoKey, infoJson);
}
QJsonObject makeInfoJson() const override { return toInfoJson(*this); }
};

//! \brief Content class for m.image
Expand Down Expand Up @@ -288,9 +291,11 @@ class PlayableContent : public UrlBasedContent<InfoT> {
{}

protected:
void fillInfoJson(QJsonObject& infoJson) const override
QJsonObject makeInfoJson() const override
{
auto infoJson = UrlBasedContent<InfoT>::makeInfoJson();
infoJson.insert("duration"_L1, duration);
return infoJson;
}

public:
Expand Down
18 changes: 10 additions & 8 deletions Quotient/events/roommessageevent.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -333,29 +333,31 @@ QString safeFileName(QString rawName)

QString RoomMessageEvent::fileNameToDownload() const
{
const auto fileInfo = get<FileContent>();
if (QUO_ALARM(fileInfo == nullptr))
const auto fileContent = get<FileContentBase>();
if (QUO_ALARM(fileContent == nullptr))
return {};

const auto fileInfo = fileContent->commonInfo();

QString fileName;
if (!fileInfo->originalName.isEmpty())
fileName = QFileInfo(safeFileName(fileInfo->originalName)).fileName();
if (!fileInfo.originalName.isEmpty())
fileName = QFileInfo(safeFileName(fileInfo.originalName)).fileName();
else if (QUrl u { plainBody() }; u.isValid()) {
qDebug(MAIN) << id()
<< "has no file name supplied but the event body "
"looks like a URL - using the file name from it";
fileName = u.fileName();
}
if (fileName.isEmpty())
return safeFileName(fileInfo->mediaId()).replace(u'.', u'-') % u'.'
% fileInfo->mimeType.preferredSuffix();
return safeFileName(fileInfo.mediaId()).replace(u'.', u'-') % u'.'
% fileInfo.mimeType.preferredSuffix();

if (QSysInfo::productType() == "windows"_L1) {
if (const auto& suffixes = fileInfo->mimeType.suffixes();
if (const auto& suffixes = fileInfo.mimeType.suffixes();
!suffixes.isEmpty() && std::ranges::none_of(suffixes, [&fileName](const QString& s) {
return fileName.endsWith(s);
}))
return fileName % u'.' % fileInfo->mimeType.preferredSuffix();
return fileName % u'.' % fileInfo.mimeType.preferredSuffix();
}
return fileName;
}
Expand Down
33 changes: 16 additions & 17 deletions Quotient/room.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1419,12 +1419,11 @@ QUrl Room::makeMediaUrl(const QString& eventId, const QUrl& mxcUrl) const
const RoomMessageEvent*
Room::Private::getEventWithFile(const QString& eventId) const
{
auto evtIt = q->findInTimeline(eventId);
if (evtIt != timeline.rend() && is<RoomMessageEvent>(**evtIt)) {
auto* event = evtIt->viewAs<RoomMessageEvent>();
if (event->has<EventContent::FileContent>())
if (auto evtIt = q->findInTimeline(eventId); evtIt != historyEdge())
if (auto* event = evtIt->viewAs<RoomMessageEvent>();
event && event->has<EventContent::FileContentBase>())
return event;
}

qCWarning(MAIN) << "No files to download in event" << eventId;
return nullptr;
}
Expand All @@ -1445,7 +1444,7 @@ QUrl Room::urlToThumbnail(const QString& eventId) const
QUrl Room::urlToDownload(const QString& eventId) const
{
if (const auto* const event = d->getEventWithFile(eventId)) {
if (const auto fileInfo = event->get<EventContent::FileContent>();
if (const auto fileInfo = event->get<EventContent::FileContentBase>();
QUO_CHECK(fileInfo != nullptr))
return connection()->getUrlForApi<DownloadFileJob>(fileInfo->url());
}
Expand Down Expand Up @@ -1742,12 +1741,13 @@ Room::Private::moveEventsToTimeline(RoomEventsRange events,
: timeline.emplace_back(std::move(e), ++index);
eventsIndex.insert(eId, index);
if (usesEncryption)
if (auto* const rme = ti.viewAs<RoomMessageEvent>())
if (const auto fileInfo = rme->get<EventContent::FileContent>()) {
if (const auto* const efm =
std::get_if<EncryptedFileMetadata>(&fileInfo->source))
FileMetadataMap::add(id, eId, *efm);
}
if (const auto* const rme = ti.viewAs<RoomMessageEvent>())
if (const auto fileContent = rme->get<EventContent::FileContentBase>())
std::visit(Overloads{ [this, &eId](const EncryptedFileMetadata& efm) {
FileMetadataMap::add(id, eId, efm);
},
[](QUrl&&) {} },
fileContent->commonInfo().source);

if (auto n = q->checkForNotifications(ti); n.type != Notification::None)
notifications.insert(eId, n);
Expand Down Expand Up @@ -2460,13 +2460,13 @@ void Room::downloadFile(const QString& eventId, const QUrl& localFilename)
Q_ASSERT(false);
return;
}
const auto fileInfo = event->get<EventContent::FileContent>();
if (!fileInfo->isValid()) {
const auto fileInfo = event->get<EventContent::FileContentBase>()->commonInfo();
if (!fileInfo.isValid()) {
qCWarning(MAIN) << "Event" << eventId
<< "has an empty or malformed mxc URL; won't download";
return;
}
const auto fileUrl = fileInfo->url();
const auto fileUrl = fileInfo.url();
auto filePath = localFilename.toLocalFile();
if (filePath.isEmpty()) { // Setup default file path
filePath = fileUrl.path().mid(1) % u'_' % event->fileNameToDownload();
Expand All @@ -2478,8 +2478,7 @@ void Room::downloadFile(const QString& eventId, const QUrl& localFilename)
qDebug(MAIN) << "File path:" << filePath;
}
DownloadFileJob *job = nullptr;
if (auto* fileMetadata =
std::get_if<EncryptedFileMetadata>(&fileInfo->source)) {
if (auto* fileMetadata = std::get_if<EncryptedFileMetadata>(&fileInfo.source)) {
job = connection()->downloadFile(fileUrl, *fileMetadata, filePath);
} else {
job = connection()->downloadFile(fileUrl, filePath);
Expand Down

0 comments on commit 16ceb7a

Please sign in to comment.