From 00ad32c5f46ff5aa51f2c29d6a2c518d4096e095 Mon Sep 17 00:00:00 2001 From: 23rd <23rd@vivaldi.net> Date: Thu, 29 Aug 2024 11:40:45 +0300 Subject: [PATCH] Added support of giveaway results messages to export to HTML. --- .../export/data/export_data_types.cpp | 26 ++++- .../export/data/export_data_types.h | 16 +++ .../export/output/export_output_html.cpp | 99 ++++++++++++++++++- .../export/output/export_output_json.cpp | 1 + 4 files changed, 138 insertions(+), 4 deletions(-) diff --git a/Telegram/SourceFiles/export/data/export_data_types.cpp b/Telegram/SourceFiles/export/data/export_data_types.cpp index 167c78039..0e3a177f3 100644 --- a/Telegram/SourceFiles/export/data/export_data_types.cpp +++ b/Telegram/SourceFiles/export/data/export_data_types.cpp @@ -753,6 +753,30 @@ GiveawayStart ParseGiveaway(const MTPDmessageMediaGiveaway &data) { return result; } +GiveawayResults ParseGiveaway(const MTPDmessageMediaGiveawayResults &data) { + const auto additional = data.vadditional_peers_count(); + auto result = GiveawayResults{ + .channel = ChannelId(data.vchannel_id()), + .untilDate = data.vuntil_date().v, + .launchId = data.vlaunch_msg_id().v, + .additionalPeersCount = additional.value_or_empty(), + .winnersCount = data.vwinners_count().v, + .unclaimedCount = data.vunclaimed_count().v, + .months = data.vmonths().value_or_empty(), + .credits = data.vstars().value_or_empty(), + .refunded = data.is_refunded(), + .all = !data.is_only_new_subscribers(), + }; + result.winners.reserve(data.vwinners().v.size()); + for (const auto &id : data.vwinners().v) { + result.winners.push_back(UserId(id)); + } + if (const auto additional = data.vprize_description()) { + result.additionalPrize = qs(*additional); + } + return result; +} + UserpicsSlice ParseUserpicsSlice( const MTPVector &data, int baseIndex) { @@ -1257,7 +1281,7 @@ Media ParseMedia( }, [&](const MTPDmessageMediaGiveaway &data) { result.content = ParseGiveaway(data); }, [&](const MTPDmessageMediaGiveawayResults &data) { - // #TODO export giveaway + result.content = ParseGiveaway(data); }, [&](const MTPDmessageMediaPaidMedia &data) { result.content = ParsePaidMedia(context, data, folder, date); }, [](const MTPDmessageMediaEmpty &data) {}); diff --git a/Telegram/SourceFiles/export/data/export_data_types.h b/Telegram/SourceFiles/export/data/export_data_types.h index a0fddab9d..371720399 100644 --- a/Telegram/SourceFiles/export/data/export_data_types.h +++ b/Telegram/SourceFiles/export/data/export_data_types.h @@ -220,6 +220,21 @@ struct GiveawayStart { bool all = false; }; +struct GiveawayResults { + ChannelId channel = 0; + std::vector winners; + QString additionalPrize; + TimeId untilDate = 0; + int32 launchId = 0; + int additionalPeersCount = 0; + int winnersCount = 0; + int unclaimedCount = 0; + int months = 0; + uint64 credits = 0; + bool refunded = false; + bool all = false; +}; + struct UserpicsSlice { std::vector list; }; @@ -353,6 +368,7 @@ struct Media { Invoice, Poll, GiveawayStart, + GiveawayResults, PaidMedia, UnsupportedMedia> content; TimeId ttl = 0; diff --git a/Telegram/SourceFiles/export/output/export_output_html.cpp b/Telegram/SourceFiles/export/output/export_output_html.cpp index a1665d17a..a36397313 100644 --- a/Telegram/SourceFiles/export/output/export_output_html.cpp +++ b/Telegram/SourceFiles/export/output/export_output_html.cpp @@ -598,7 +598,8 @@ private: const Data::Message &message, const QString &basePath, const PeersMap &peers, - const QString &internalLinksDomain); + const QString &internalLinksDomain, + Fn wrapMessageLink); [[nodiscard]] QByteArray pushGenericMedia(const MediaData &data); [[nodiscard]] QByteArray pushStickerMedia( const Data::Document &data, @@ -616,6 +617,10 @@ private: [[nodiscard]] QByteArray pushGiveaway( const PeersMap &peers, const Data::GiveawayStart &data); + [[nodiscard]] QByteArray pushGiveaway( + const PeersMap &peers, + const Data::GiveawayResults &data, + Fn wrapMessageLink); File _file; QByteArray _composedStart; @@ -1456,7 +1461,13 @@ auto HtmlWriter::Wrap::pushMessage( block.append(popTag()); } - block.append(pushMedia(message, basePath, peers, internalLinksDomain)); + block.append( + pushMedia( + message, + basePath, + peers, + internalLinksDomain, + wrapMessageLink)); const auto text = FormatText(message.text, internalLinksDomain, _base); if (!text.isEmpty()) { @@ -1559,7 +1570,8 @@ QByteArray HtmlWriter::Wrap::pushMedia( const Data::Message &message, const QString &basePath, const PeersMap &peers, - const QString &internalLinksDomain) { + const QString &internalLinksDomain, + Fn wrapMessageLink) { const auto data = prepareMediaData( message, basePath, @@ -1587,6 +1599,8 @@ QByteArray HtmlWriter::Wrap::pushMedia( return pushPoll(*poll); } else if (const auto giveaway = std::get_if(&content)) { return pushGiveaway(peers, *giveaway); + } else if (const auto giveaway = std::get_if(&content)) { + return pushGiveaway(peers, *giveaway, wrapMessageLink); } Assert(v::is_null(content)); return QByteArray(); @@ -2054,6 +2068,84 @@ QByteArray HtmlWriter::Wrap::pushGiveaway( return result; } +QByteArray HtmlWriter::Wrap::pushGiveaway( + const PeersMap &peers, + const Data::GiveawayResults &data, + Fn wrapMessageLink) { + auto result = pushDiv("media_wrap clearfix"); + result.append(pushDiv("media_giveaway")); + + result.append(pushDiv("section_title bold")); + result.append((data.winnersCount > 1) + ? SerializeString("Winners Selected!") + : SerializeString("Winner Selected!")); + result.append(popTag()); + + result.append(pushDiv("section_body")); + result.append( + "" + Data::NumberToString(data.winnersCount) + " " + + SerializeString((data.winnersCount > 1) ? "winners" : "winner") + + " of the " + + wrapMessageLink(data.launchId, "Giveaway") + + " was randomly selected by Telegram."); + result.append(popTag()); + + result.append(pushDiv("section_title bold")); + result.append((data.winnersCount > 1) + ? SerializeString("Winners") + : SerializeString("Winner")); + result.append(popTag()); + + result.append(pushDiv("section_body")); + auto winners = QByteArrayList(); + for (const auto &winner : data.winners) { + winners.append("" + peers.wrapPeerName(winner) + ""); + } + const auto andMore = [&, size = data.winners.size()] { + if (data.winnersCount > size) { + return SerializeString(" and ") + + Data::NumberToString(data.winnersCount - size) + + SerializeString(" more!"); + } + return QByteArray(); + }(); + result.append(winners.join(", ") + andMore); + result.append(popTag()); + + result.append(pushDiv("section_body")); + const auto prize = [&, singleStar = (data.credits == 1)] { + if (data.credits && data.winnersCount == 1) { + return SerializeString("The winner received ") + + "" + + Data::NumberToString(data.credits) + + "" + + SerializeString(singleStar ? " Star." : " Stars."); + } else if (data.credits && data.winnersCount > 1) { + return SerializeString("All winners received ") + + "" + + Data::NumberToString(data.credits) + + "" + + SerializeString(singleStar + ? " Star in total." + : " Stars in total."); + } else if (data.unclaimedCount) { + return SerializeString("Some winners couldn't be selected."); + } else if (data.winnersCount == 1) { + return SerializeString( + "The winner received their gift link in a private message."); + } else if (data.winnersCount > 1) { + return SerializeString( + "All winners received gift links in private messages."); + } + }(); + result.append(prize); + result.append(popTag()); + + result.append(popTag()); + result.append(popTag()); + return result; +} + MediaData HtmlWriter::Wrap::prepareMediaData( const Data::Message &message, const QString &basePath, @@ -2213,6 +2305,7 @@ MediaData HtmlWriter::Wrap::prepareMediaData( result.status = Data::FormatMoneyAmount(data.amount, data.currency); }, [](const Poll &data) { }, [](const GiveawayStart &data) { + }, [](const GiveawayResults &data) { }, [&](const PaidMedia &data) { result.classes = "media_invoice"; result.status = Data::FormatMoneyAmount(data.stars, "XTR"); diff --git a/Telegram/SourceFiles/export/output/export_output_json.cpp b/Telegram/SourceFiles/export/output/export_output_json.cpp index a61420ca4..38d687ab1 100644 --- a/Telegram/SourceFiles/export/output/export_output_json.cpp +++ b/Telegram/SourceFiles/export/output/export_output_json.cpp @@ -799,6 +799,7 @@ QByteArray SerializeMessage( { "until_date", SerializeDate(data.untilDate) }, { "channels", serialized }, })); + }, [&](const GiveawayResults &data) { }, [&](const PaidMedia &data) { push("paid_stars_amount", data.stars); }, [](const UnsupportedMedia &data) {