From b9250edb33bbba48ede204658636a6a7ee6cb167 Mon Sep 17 00:00:00 2001 From: John Preston Date: Sun, 24 Jun 2018 02:34:47 +0100 Subject: [PATCH] Some more export data improvements. --- .../export/data/export_data_about.h | 19 +++++- .../SourceFiles/export/export_api_wrap.cpp | 34 +++++------ Telegram/SourceFiles/export/export_api_wrap.h | 2 +- .../export/output/export_output_html.cpp | 60 ++++++++++++++++--- .../export/output/export_output_text.cpp | 8 ++- .../export/view/export_view_content.cpp | 22 +++---- 6 files changed, 106 insertions(+), 39 deletions(-) diff --git a/Telegram/SourceFiles/export/data/export_data_about.h b/Telegram/SourceFiles/export/data/export_data_about.h index 9fdc67290f4ab..d2077e74a84fb 100644 --- a/Telegram/SourceFiles/export/data/export_data_about.h +++ b/Telegram/SourceFiles/export/data/export_data_about.h @@ -12,6 +12,23 @@ For license and copyright information please follow this link: namespace Export { namespace Data { +inline Utf8String AboutTelegram() { + return "Here is all the data you requested. " + "Remember: we don\xE2\x80\x99""t use your data for ad targeting, " + "we don\xE2\x80\x99""t sell it to others, " + "and we\xE2\x80\x99""re not part of any " + "\xE2\x80\x9C""family of companies.\xE2\x80\x9D\n\n" + "Telegram only keeps the information it needs to function " + "as a feature-rich cloud service \xE2\x80\x93 for example, " + "your cloud chats so that you can access them " + "from any devices without using third-party backups, " + "or your contacts so that you can rely " + "on your existing social graph " + "when messaging people on Telegram.\n\n" + "Check out Settings > Privacy & Security " + "on Telegram's mobile apps for relevant settings."; +} + inline Utf8String AboutContacts() { return "If you allow access, your contacts are continuously synced " "with Telegram. Thanks to this, you can easily switch to Telegram " @@ -38,7 +55,7 @@ inline Utf8String AboutFrequent() { "(requires Telegram for iOS v.4.8.3 " "or Telegram for Android v.4.8.10 or higher). " "See this page for more information: " - "https://telegram.org/faq/data-export"; + "https://telegram.org/faq_export"; } inline Utf8String AboutSessions() { diff --git a/Telegram/SourceFiles/export/export_api_wrap.cpp b/Telegram/SourceFiles/export/export_api_wrap.cpp index 7f5316b54ecfd..3ed629756bd82 100644 --- a/Telegram/SourceFiles/export/export_api_wrap.cpp +++ b/Telegram/SourceFiles/export/export_api_wrap.cpp @@ -317,7 +317,7 @@ void ApiWrap::startExport( if (_settings->types & Settings::Type::Userpics) { _startProcess->steps.push_back(Step::UserpicsCount); } - if (_settings->types & Settings::Type::NonChannelChatsMask) { + if (_settings->types & Settings::Type::AnyChatsMask) { _startProcess->steps.push_back(Step::SplitRanges); } if (_settings->types & Settings::Type::AnyChatsMask) { @@ -384,6 +384,15 @@ void ApiWrap::requestSplitRanges() { mainRequest(MTPmessages_GetSplitRanges( )).done([=](const MTPVector &result) { _splits = result.v; + if (_splits.empty()) { + _splits.push_back(MTP_messageRange( + MTP_int(1), + MTP_int(std::numeric_limits::max()))); + } + _startProcess->splitIndex = useOnlyLastSplit() + ? (_splits.size() - 1) + : 0; + sendNextStartRequest(); }).send(); } @@ -391,8 +400,6 @@ void ApiWrap::requestSplitRanges() { void ApiWrap::requestDialogsCount() { Expects(_startProcess != nullptr); - validateSplits(); - splitRequest(_startProcess->splitIndex, MTPmessages_GetDialogs( MTP_flags(0), MTP_int(0), // offset_date @@ -440,13 +447,15 @@ void ApiWrap::finishStartProcess() { process->done(process->info); } +bool ApiWrap::useOnlyLastSplit() const { + return !(_settings->types & Settings::Type::NonChannelChatsMask); +} + void ApiWrap::requestLeftChannelsList( Fn progress, FnMut done) { Expects(_leftChannelsProcess != nullptr); - validateSplits(); - _leftChannelsProcess->progress = std::move(progress); _leftChannelsProcess->done = std::move(done); requestLeftChannelsSlice(); @@ -471,8 +480,6 @@ void ApiWrap::requestDialogsList( FnMut done) { Expects(_dialogsProcess == nullptr); - validateSplits(); - _dialogsProcess = std::make_unique(); _dialogsProcess->splitIndexPlusOne = _splits.size(); _dialogsProcess->progress = std::move(progress); @@ -481,14 +488,6 @@ void ApiWrap::requestDialogsList( requestDialogsSlice(); } -void ApiWrap::validateSplits() { - if (_splits.empty()) { - _splits.push_back(MTP_messageRange( - MTP_int(1), - MTP_int(std::numeric_limits::max()))); - } -} - void ApiWrap::startMainSession(FnMut done) { const auto sizeLimit = _settings->media.sizeLimit; const auto hasFiles = (_settings->media.types != 0) && (sizeLimit > 0); @@ -884,7 +883,8 @@ void ApiWrap::requestDialogsSlice() { _dialogsProcess->offsetId = last.topMessageId; _dialogsProcess->offsetDate = last.topMessageDate; _dialogsProcess->offsetPeer = last.input; - } else if (--_dialogsProcess->splitIndexPlusOne > 0) { + } else if (!useOnlyLastSplit() + && --_dialogsProcess->splitIndexPlusOne > 0) { _dialogsProcess->offsetId = 0; _dialogsProcess->offsetDate = 0; _dialogsProcess->offsetPeer = MTP_inputPeerEmpty(); @@ -1185,7 +1185,7 @@ bool ApiWrap::processFileLoad( } }, [](const auto &data) { return Type::Photo; - }) : Type::Photo; + }) : Type(0); if ((_settings->media.types & type) != type) { file.skipReason = SkipReason::FileType; diff --git a/Telegram/SourceFiles/export/export_api_wrap.h b/Telegram/SourceFiles/export/export_api_wrap.h index 7e5a59c6e2764..564b5429878e8 100644 --- a/Telegram/SourceFiles/export/export_api_wrap.h +++ b/Telegram/SourceFiles/export/export_api_wrap.h @@ -123,7 +123,7 @@ class ApiWrap { void otherDataDone(const QString &relativePath); - void validateSplits(); + bool useOnlyLastSplit() const; void requestDialogsSlice(); void appendDialogsSlice(Data::DialogsInfo &&info); diff --git a/Telegram/SourceFiles/export/output/export_output_html.cpp b/Telegram/SourceFiles/export/output/export_output_html.cpp index 9bfda6cd3cd49..373c186d54f69 100644 --- a/Telegram/SourceFiles/export/output/export_output_html.cpp +++ b/Telegram/SourceFiles/export/output/export_output_html.cpp @@ -67,6 +67,45 @@ QByteArray SerializeString(const QByteArray &value) { return result; } +QByteArray MakeLinks(const QByteArray &value) { + const auto domain = QByteArray("https://telegram.org/"); + auto result = QByteArray(); + auto offset = 0; + while (true) { + const auto start = value.indexOf(domain, offset); + if (start < 0) { + break; + } + auto end = start + domain.size(); + for (; end != value.size(); ++end) { + const auto ch = value[end]; + if ((ch < 'a' || ch > 'z') + && (ch < 'A' || ch > 'Z') + && (ch < '0' || ch > '9') + && (ch != '-') + && (ch != '_') + && (ch != '/')) { + break; + } + } + if (start > offset) { + const auto link = value.mid(start, end - start); + result.append(value.mid(offset, start - offset)); + result.append(""); + result.append(link); + result.append(""); + offset = end; + } + } + if (result.isEmpty()) { + return value; + } + if (offset < value.size()) { + result.append(value.mid(offset)); + } + return result; +} + void SerializeMultiline( QByteArray &appendTo, const QByteArray &value, @@ -655,7 +694,14 @@ Result HtmlWriter::start(const Settings &settings, Stats *stats) { //if (!result) { // return result; //} - return copyFile(":/export/css/style.css", "css/style.css"); + const auto result = copyFile(":/export/css/style.css", "css/style.css"); + if (!result) { + return result; + } + return _summary->writeBlock( + MakeLinks(SerializeString(Data::AboutTelegram())) + + kLineBreak + + kLineBreak); } Result HtmlWriter::writePersonal(const Data::PersonalInfo &data) { @@ -728,7 +774,7 @@ Result HtmlWriter::writeUserpicsSlice(const Data::UserpicsSlice &data) { }(); lines.push_back(SerializeKeyValue({ { - "Date", + "Added", SerializeString(Data::FormatDateTime(userpic.date)) }, { "Photo", path }, @@ -787,7 +833,7 @@ Result HtmlWriter::writeSavedContacts(const Data::ContactsList &data) { })); } } - const auto full = SerializeString(Data::AboutContacts()) + const auto full = MakeLinks(SerializeString(Data::AboutContacts())) + kLineBreak + kLineBreak + JoinList(kLineBreak, list); @@ -876,7 +922,7 @@ Result HtmlWriter::writeFrequentContacts(const Data::ContactsList &data) { writeList(data.correspondents, "People"); writeList(data.inlineBots, "Inline bots"); writeList(data.phoneCalls, "Calls"); - const auto full = SerializeString(Data::AboutFrequent()) + const auto full = MakeLinks(SerializeString(Data::AboutFrequent())) + kLineBreak + kLineBreak + JoinList(kLineBreak, list); @@ -942,7 +988,7 @@ Result HtmlWriter::writeSessions(const Data::SessionsList &data) { { "Created", Data::FormatDateTime(session.created) }, })); } - const auto full = SerializeString(Data::AboutSessions()) + const auto full = MakeLinks(SerializeString(Data::AboutSessions())) + kLineBreak + kLineBreak + JoinList(kLineBreak, list); @@ -1000,7 +1046,7 @@ Result HtmlWriter::writeWebSessions(const Data::SessionsList &data) { }, })); } - const auto full = SerializeString(Data::AboutWebSessions()) + const auto full = MakeLinks(SerializeString(Data::AboutWebSessions())) + kLineBreak + kLineBreak + JoinList(kLineBreak, list); @@ -1094,7 +1140,7 @@ Result HtmlWriter::writeChatsStart( _dialogIndex = 0; _dialogsCount = data.list.size(); - const auto block = SerializeString(about) + kLineBreak; + const auto block = MakeLinks(SerializeString(about)) + kLineBreak; if (const auto result = _chats->writeBlock(block); !result) { return result; } diff --git a/Telegram/SourceFiles/export/output/export_output_text.cpp b/Telegram/SourceFiles/export/output/export_output_text.cpp index 4c578c4cf5b95..6caa06d84682c 100644 --- a/Telegram/SourceFiles/export/output/export_output_text.cpp +++ b/Telegram/SourceFiles/export/output/export_output_text.cpp @@ -448,7 +448,9 @@ Result TextWriter::start(const Settings &settings, Stats *stats) { _settings = base::duplicate(settings); _stats = stats; _summary = fileWithRelativePath(mainFileRelativePath()); - return Result::Success(); + return _summary->writeBlock(Data::AboutTelegram() + + kLineBreak + + kLineBreak); } Result TextWriter::writePersonal(const Data::PersonalInfo &data) { @@ -513,7 +515,7 @@ Result TextWriter::writeUserpicsSlice(const Data::UserpicsSlice &data) { Unexpected("Skip reason while writing photo path."); }(); lines.push_back(SerializeKeyValue({ - { "Date", Data::FormatDateTime(userpic.date) }, + { "Added", Data::FormatDateTime(userpic.date) }, { "Photo", path }, })); } @@ -560,7 +562,7 @@ Result TextWriter::writeSavedContacts(const Data::ContactsList &data) { "Phone number", Data::FormatPhoneNumber(contact.phoneNumber) }, - { "Date", Data::FormatDateTime(contact.date) } + { "Added", Data::FormatDateTime(contact.date) } })); } } diff --git a/Telegram/SourceFiles/export/view/export_view_content.cpp b/Telegram/SourceFiles/export/view/export_view_content.cpp index f358a2d13d8a5..8f692082de255 100644 --- a/Telegram/SourceFiles/export/view/export_view_content.cpp +++ b/Telegram/SourceFiles/export/view/export_view_content.cpp @@ -86,17 +86,19 @@ Content ContentFromState(const ProcessingState &state) { case Step::LeftChannels: case Step::Dialogs: pushMain(lang(lng_export_state_chats)); - if (state.itemCount > 0) { - push( - "chat" + QString::number(state.entityIndex), - (state.entityName.isEmpty() - ? lang(lng_deleted) - : state.entityName), - (QString::number(state.itemIndex) + push( + "chat" + QString::number(state.entityIndex), + (state.entityName.isEmpty() + ? lang(lng_deleted) + : state.entityName), + (state.itemCount > 0 + ? (QString::number(state.itemIndex) + " / " - + QString::number(state.itemCount)), - state.itemIndex / float64(state.itemCount)); - } + + QString::number(state.itemCount)) + : QString()), + (state.itemCount > 0 + ? (state.itemIndex / float64(state.itemCount)) + : 0.)); pushBytes( ("file" + QString::number(state.entityIndex)