tdesktop/Telegram/SourceFiles/export/data/export_data_types.h
2023-10-26 14:08:41 +04:00

824 lines
15 KiB
C++

/*
This file is part of Telegram Desktop,
the official desktop application for the Telegram messaging service.
For license and copyright information please follow this link:
https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
*/
#pragma once
#include "scheme.h"
#include "base/optional.h"
#include "base/variant.h"
#include "data/data_peer_id.h"
#include <QtCore/QSize>
#include <QtCore/QString>
#include <QtCore/QByteArray>
#include <vector>
namespace Export {
struct Settings;
namespace Data {
using Utf8String = QByteArray;
int PeerColorIndex(BareId bareId);
BareId PeerToBareId(PeerId peerId);
int PeerColorIndex(PeerId peerId);
int ApplicationColorIndex(int applicationId);
int DomainApplicationId(const Utf8String &data);
Utf8String ParseString(const MTPstring &data);
Utf8String FillLeft(const Utf8String &data, int length, char filler);
template <typename Type>
inline auto NumberToString(Type value, int length = 0, char filler = '0')
-> std::enable_if_t<std::is_arithmetic_v<Type>, Utf8String> {
const auto result = std::to_string(value);
return FillLeft(
Utf8String(result.data(), int(result.size())),
length,
filler).replace(',', '.');
}
struct UserpicsInfo {
int count = 0;
};
struct StoriesInfo {
int count = 0;
};
struct FileLocation {
int dcId = 0;
MTPInputFileLocation data;
explicit operator bool() const {
return dcId != 0;
}
};
bool RefreshFileReference(FileLocation &to, const FileLocation &from);
struct File {
enum class SkipReason {
None,
Unavailable,
FileType,
FileSize,
DateLimits,
};
FileLocation location;
int64 size = 0;
QByteArray content;
QString suggestedPath;
QString relativePath;
SkipReason skipReason = SkipReason::None;
};
struct Image {
int width = 0;
int height = 0;
File file;
};
std::pair<QString, QSize> WriteImageThumb(
const QString &basePath,
const QString &largePath,
Fn<QSize(QSize)> convertSize,
std::optional<QByteArray> format = std::nullopt,
std::optional<int> quality = std::nullopt,
const QString &postfix = "_thumb");
QString WriteImageThumb(
const QString &basePath,
const QString &largePath,
int width,
int height,
const QString &postfix = "_thumb");
struct ContactInfo {
UserId userId = 0;
Utf8String firstName;
Utf8String lastName;
Utf8String phoneNumber;
TimeId date = 0;
Utf8String name() const;
};
ContactInfo ParseContactInfo(const MTPUser &data);
int ContactColorIndex(const ContactInfo &data);
struct Photo {
uint64 id = 0;
TimeId date = 0;
Image image;
};
struct Document {
uint64 id = 0;
TimeId date = 0;
File file;
Image thumb;
Utf8String name;
Utf8String mime;
int width = 0;
int height = 0;
Utf8String stickerEmoji;
Utf8String songPerformer;
Utf8String songTitle;
int duration = 0;
bool isSticker = false;
bool isAnimated = false;
bool isVideoMessage = false;
bool isVoiceMessage = false;
bool isVideoFile = false;
bool isAudioFile = false;
};
struct SharedContact {
ContactInfo info;
File vcard;
};
struct GeoPoint {
float64 latitude = 0.;
float64 longitude = 0.;
bool valid = false;
};
struct Venue {
GeoPoint point;
Utf8String title;
Utf8String address;
};
struct Game {
uint64 id = 0;
Utf8String shortName;
Utf8String title;
Utf8String description;
UserId botId = 0;
};
struct Invoice {
Utf8String title;
Utf8String description;
Utf8String currency;
uint64 amount = 0;
int32 receiptMsgId = 0;
};
struct Poll {
struct Answer {
Utf8String text;
QByteArray option;
int votes = 0;
bool my = false;
};
uint64 id = 0;
Utf8String question;
std::vector<Answer> answers;
int totalVotes = 0;
bool closed = false;
};
struct Giveaway {
std::vector<ChannelId> channels;
TimeId untilDate = 0;
int quantity = 0;
int months = 0;
};
struct UserpicsSlice {
std::vector<Photo> list;
};
UserpicsSlice ParseUserpicsSlice(
const MTPVector<MTPPhoto> &data,
int baseIndex);
struct User {
PeerId id() const;
BareId bareId = 0;
ContactInfo info;
Utf8String username;
bool isBot = false;
bool isSelf = false;
bool isReplies = false;
MTPInputUser input = MTP_inputUserEmpty();
Utf8String name() const;
};
User ParseUser(const MTPUser &data);
std::map<UserId, User> ParseUsersList(const MTPVector<MTPUser> &data);
struct Chat {
PeerId id() const;
BareId bareId = 0;
ChannelId migratedToChannelId = 0;
Utf8String title;
Utf8String username;
bool isBroadcast = false;
bool isSupergroup = false;
MTPInputPeer input = MTP_inputPeerEmpty();
};
Chat ParseChat(const MTPChat &data);
std::map<PeerId, Chat> ParseChatsList(const MTPVector<MTPChat> &data);
struct Peer {
PeerId id() const;
Utf8String name() const;
MTPInputPeer input() const;
const User *user() const;
const Chat *chat() const;
std::variant<User, Chat> data;
};
std::map<PeerId, Peer> ParsePeersLists(
const MTPVector<MTPUser> &users,
const MTPVector<MTPChat> &chats);
struct PersonalInfo {
User user;
Utf8String bio;
};
PersonalInfo ParsePersonalInfo(const MTPDusers_userFull &data);
struct TopPeer {
Peer peer;
float64 rating = 0.;
};
struct ContactsList {
std::vector<ContactInfo> list;
std::vector<TopPeer> correspondents;
std::vector<TopPeer> inlineBots;
std::vector<TopPeer> phoneCalls;
};
ContactsList ParseContactsList(const MTPcontacts_Contacts &data);
ContactsList ParseContactsList(const MTPVector<MTPSavedContact> &data);
std::vector<int> SortedContactsIndices(const ContactsList &data);
bool AppendTopPeers(ContactsList &to, const MTPcontacts_TopPeers &data);
struct Session {
int applicationId = 0;
Utf8String platform;
Utf8String deviceModel;
Utf8String systemVersion;
Utf8String applicationName;
Utf8String applicationVersion;
TimeId created = 0;
TimeId lastActive = 0;
Utf8String ip;
Utf8String country;
Utf8String region;
};
struct WebSession {
Utf8String botUsername;
Utf8String domain;
Utf8String browser;
Utf8String platform;
TimeId created = 0;
TimeId lastActive = 0;
Utf8String ip;
Utf8String region;
};
struct SessionsList {
std::vector<Session> list;
std::vector<WebSession> webList;
};
SessionsList ParseSessionsList(const MTPaccount_Authorizations &data);
SessionsList ParseWebSessionsList(const MTPaccount_WebAuthorizations &data);
struct UnsupportedMedia {
};
struct Media {
std::variant<
v::null_t,
Photo,
Document,
SharedContact,
GeoPoint,
Venue,
Game,
Invoice,
Poll,
Giveaway,
UnsupportedMedia> content;
TimeId ttl = 0;
File &file();
const File &file() const;
Image &thumb();
const Image &thumb() const;
};
struct ParseMediaContext {
PeerId selfPeerId = 0;
int photos = 0;
int audios = 0;
int videos = 0;
int files = 0;
int contacts = 0;
UserId botId = 0;
};
Document ParseDocument(
ParseMediaContext &context,
const MTPDocument &data,
const QString &suggestedFolder,
TimeId date);
Media ParseMedia(
ParseMediaContext &context,
const MTPMessageMedia &data,
const QString &folder,
TimeId date);
struct ActionChatCreate {
Utf8String title;
std::vector<UserId> userIds;
};
struct ActionChatEditTitle {
Utf8String title;
};
struct ActionChatEditPhoto {
Photo photo;
};
struct ActionChatDeletePhoto {
};
struct ActionChatAddUser {
std::vector<UserId> userIds;
};
struct ActionChatDeleteUser {
UserId userId = 0;
};
struct ActionChatJoinedByLink {
UserId inviterId = 0;
};
struct ActionChannelCreate {
Utf8String title;
};
struct ActionChatMigrateTo {
ChannelId channelId = 0;
};
struct ActionChannelMigrateFrom {
Utf8String title;
ChatId chatId = 0;
};
struct ActionPinMessage {
};
struct ActionHistoryClear {
};
struct ActionGameScore {
uint64 gameId = 0;
int score = 0;
};
struct ActionPaymentSent {
Utf8String currency;
uint64 amount = 0;
bool recurringInit = false;
bool recurringUsed = false;
};
struct ActionPhoneCall {
enum class DiscardReason {
Unknown,
Missed,
Disconnect,
Hangup,
Busy,
};
DiscardReason discardReason = DiscardReason::Unknown;
int duration = 0;
};
struct ActionScreenshotTaken {
};
struct ActionCustomAction {
Utf8String message;
};
struct ActionBotAllowed {
uint64 appId = 0;
Utf8String app;
Utf8String domain;
bool attachMenu = false;
bool fromRequest = false;
};
struct ActionSecureValuesSent {
enum class Type {
PersonalDetails,
Passport,
DriverLicense,
IdentityCard,
InternalPassport,
Address,
UtilityBill,
BankStatement,
RentalAgreement,
PassportRegistration,
TemporaryRegistration,
Phone,
Email,
};
std::vector<Type> types;
};
struct ActionContactSignUp {
};
struct ActionPhoneNumberRequest {
};
struct ActionGeoProximityReached {
PeerId fromId = 0;
PeerId toId = 0;
int distance = 0;
bool fromSelf = false;
bool toSelf = false;
};
struct ActionGroupCall {
int duration = 0;
};
struct ActionInviteToGroupCall {
std::vector<UserId> userIds;
};
struct ActionSetMessagesTTL {
TimeId period = 0;
};
struct ActionGroupCallScheduled {
TimeId date = 0;
};
struct ActionSetChatTheme {
QString emoji;
};
struct ActionChatJoinedByRequest {
};
struct ActionWebViewDataSent {
Utf8String text;
};
struct ActionGiftPremium {
Utf8String cost;
int months;
};
struct ActionTopicCreate {
Utf8String title;
};
struct ActionTopicEdit {
Utf8String title;
std::optional<uint64> iconEmojiId = 0;
};
struct ActionSuggestProfilePhoto {
Photo photo;
};
struct ActionSetChatWallPaper {
// #TODO wallpapers
};
struct ActionSetSameChatWallPaper {
};
struct ActionGiftCode {
QByteArray code;
PeerId boostPeerId = 0;
int months = 0;
bool viaGiveaway = false;
};
struct ActionRequestedPeer {
PeerId peerId = 0;
int buttonId = 0;
};
struct ActionGiveawayLaunch {
};
struct ServiceAction {
std::variant<
v::null_t,
ActionChatCreate,
ActionChatEditTitle,
ActionChatEditPhoto,
ActionChatDeletePhoto,
ActionChatAddUser,
ActionChatDeleteUser,
ActionChatJoinedByLink,
ActionChannelCreate,
ActionChatMigrateTo,
ActionChannelMigrateFrom,
ActionPinMessage,
ActionHistoryClear,
ActionGameScore,
ActionPaymentSent,
ActionPhoneCall,
ActionScreenshotTaken,
ActionCustomAction,
ActionBotAllowed,
ActionSecureValuesSent,
ActionContactSignUp,
ActionPhoneNumberRequest,
ActionGeoProximityReached,
ActionGroupCall,
ActionInviteToGroupCall,
ActionSetMessagesTTL,
ActionGroupCallScheduled,
ActionSetChatTheme,
ActionChatJoinedByRequest,
ActionWebViewDataSent,
ActionGiftPremium,
ActionTopicCreate,
ActionTopicEdit,
ActionSuggestProfilePhoto,
ActionRequestedPeer,
ActionSetChatWallPaper,
ActionSetSameChatWallPaper,
ActionGiftCode,
ActionGiveawayLaunch> content;
};
ServiceAction ParseServiceAction(
ParseMediaContext &context,
const MTPMessageAction &data,
const QString &mediaFolder);
struct TextPart {
enum class Type {
Text,
Unknown,
Mention,
Hashtag,
BotCommand,
Url,
Email,
Bold,
Italic,
Code,
Pre,
TextUrl,
MentionName,
Phone,
Cashtag,
Underline,
Strike,
Blockquote,
BankCard,
Spoiler,
CustomEmoji,
};
Type type = Type::Text;
Utf8String text;
Utf8String additional;
[[nodiscard]] static Utf8String UnavailableEmoji() {
return "(unavailable)";
}
};
struct MessageId {
ChannelId channelId;
int32 msgId = 0;
};
inline bool operator==(MessageId a, MessageId b) {
return (a.channelId == b.channelId) && (a.msgId == b.msgId);
}
inline bool operator!=(MessageId a, MessageId b) {
return !(a == b);
}
inline bool operator<(MessageId a, MessageId b) {
return (a.channelId < b.channelId)
|| (a.channelId == b.channelId && a.msgId < b.msgId);
}
inline bool operator>(MessageId a, MessageId b) {
return (b < a);
}
inline bool operator<=(MessageId a, MessageId b) {
return !(b < a);
}
inline bool operator>=(MessageId a, MessageId b) {
return !(a < b);
}
struct Message {
int32 id = 0;
TimeId date = 0;
TimeId edited = 0;
PeerId fromId = 0;
PeerId peerId = 0;
PeerId selfId = 0;
PeerId forwardedFromId = 0;
Utf8String forwardedFromName;
TimeId forwardedDate = 0;
bool forwarded = false;
bool showForwardedAsOriginal = false;
PeerId savedFromChatId = 0;
Utf8String signature;
UserId viaBotId = 0;
int32 replyToMsgId = 0;
PeerId replyToPeerId = 0;
std::vector<TextPart> text;
Media media;
ServiceAction action;
bool out = false;
File &file();
const File &file() const;
Image &thumb();
const Image &thumb() const;
};
struct FileOrigin {
int split = 0;
MTPInputPeer peer;
int32 messageId = 0;
int32 storyId = 0;
uint64 customEmojiId = 0;
};
struct Story {
int32 id = 0;
TimeId date = 0;
TimeId expires = 0;
Media media;
bool pinned = false;
std::vector<TextPart> caption;
File &file();
const File &file() const;
Image &thumb();
const Image &thumb() const;
};
struct StoriesSlice {
std::vector<Story> list;
int32 lastId = 0;
int skipped = 0;
};
StoriesSlice ParseStoriesSlice(
const MTPVector<MTPStoryItem> &data,
int baseIndex);
Message ParseMessage(
ParseMediaContext &context,
const MTPMessage &data,
const QString &mediaFolder);
std::map<MessageId, Message> ParseMessagesList(
PeerId selfId,
const MTPVector<MTPMessage> &data,
const QString &mediaFolder);
struct DialogInfo {
enum class Type {
Unknown,
Self,
Replies,
Personal,
Bot,
PrivateGroup,
PrivateSupergroup,
PublicSupergroup,
PrivateChannel,
PublicChannel,
};
Type type = Type::Unknown;
Utf8String name;
Utf8String lastName;
MTPInputPeer input = MTP_inputPeerEmpty();
int32 topMessageId = 0;
TimeId topMessageDate = 0;
PeerId peerId = 0;
MTPInputPeer migratedFromInput = MTP_inputPeerEmpty();
ChannelId migratedToChannelId = 0;
// User messages splits which contained that dialog.
std::vector<int> splits;
// Filled after the whole dialogs list is accumulated.
bool onlyMyMessages = false;
bool isLeftChannel = false;
QString relativePath;
// Filled when requesting dialog messages.
std::vector<int> messagesCountPerSplit;
};
struct DialogsInfo {
DialogInfo *item(int index);
const DialogInfo *item(int index) const;
std::vector<DialogInfo> chats;
std::vector<DialogInfo> left;
};
DialogInfo::Type DialogTypeFromChat(const Chat &chat);
DialogsInfo ParseDialogsInfo(const MTPmessages_Dialogs &data);
DialogsInfo ParseDialogsInfo(
const MTPInputPeer &singlePeer,
const MTPVector<MTPUser> &data);
DialogsInfo ParseDialogsInfo(
const MTPInputPeer &singlePeer,
const MTPmessages_Chats &data);
DialogsInfo ParseLeftChannelsInfo(const MTPmessages_Chats &data);
bool AddMigrateFromSlice(
DialogInfo &to,
const DialogInfo &from,
int splitIndex,
int splitsCount);
void FinalizeDialogsInfo(DialogsInfo &info, const Settings &settings);
struct MessagesSlice {
std::vector<Message> list;
std::map<PeerId, Peer> peers;
};
MessagesSlice ParseMessagesSlice(
ParseMediaContext &context,
const MTPVector<MTPMessage> &data,
const MTPVector<MTPUser> &users,
const MTPVector<MTPChat> &chats,
const QString &mediaFolder);
MessagesSlice AdjustMigrateMessageIds(MessagesSlice slice);
bool SingleMessageBefore(
const MTPmessages_Messages &data,
TimeId date);
bool SingleMessageAfter(
const MTPmessages_Messages &data,
TimeId date);
bool SkipMessageByDate(const Message &message, const Settings &settings);
Utf8String FormatPhoneNumber(const Utf8String &phoneNumber);
Utf8String FormatDateTime(
TimeId date,
bool hasTimeZone = false,
QChar dateSeparator = QChar('.'),
QChar timeSeparator = QChar(':'),
QChar separator = QChar(' '));
Utf8String FormatMoneyAmount(int64 amount, const Utf8String &currency);
Utf8String FormatFileSize(int64 size);
Utf8String FormatDuration(int64 seconds);
} // namespace Data
} // namespace Export