mirror of
https://github.com/telegramdesktop/tdesktop
synced 2025-03-31 15:59:54 +00:00
Some more export data improvements.
This commit is contained in:
parent
54cab2c5a5
commit
b9250edb33
Telegram/SourceFiles/export
@ -12,6 +12,23 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
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() {
|
||||
|
@ -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<MTPMessageRange> &result) {
|
||||
_splits = result.v;
|
||||
if (_splits.empty()) {
|
||||
_splits.push_back(MTP_messageRange(
|
||||
MTP_int(1),
|
||||
MTP_int(std::numeric_limits<int>::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<bool(int count)> progress,
|
||||
FnMut<void(Data::DialogsInfo&&)> done) {
|
||||
Expects(_leftChannelsProcess != nullptr);
|
||||
|
||||
validateSplits();
|
||||
|
||||
_leftChannelsProcess->progress = std::move(progress);
|
||||
_leftChannelsProcess->done = std::move(done);
|
||||
requestLeftChannelsSlice();
|
||||
@ -471,8 +480,6 @@ void ApiWrap::requestDialogsList(
|
||||
FnMut<void(Data::DialogsInfo&&)> done) {
|
||||
Expects(_dialogsProcess == nullptr);
|
||||
|
||||
validateSplits();
|
||||
|
||||
_dialogsProcess = std::make_unique<DialogsProcess>();
|
||||
_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<int>::max())));
|
||||
}
|
||||
}
|
||||
|
||||
void ApiWrap::startMainSession(FnMut<void()> 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;
|
||||
|
@ -123,7 +123,7 @@ private:
|
||||
|
||||
void otherDataDone(const QString &relativePath);
|
||||
|
||||
void validateSplits();
|
||||
bool useOnlyLastSplit() const;
|
||||
|
||||
void requestDialogsSlice();
|
||||
void appendDialogsSlice(Data::DialogsInfo &&info);
|
||||
|
@ -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("<a href=\"").append(link).append("\">");
|
||||
result.append(link);
|
||||
result.append("</a>");
|
||||
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;
|
||||
}
|
||||
|
@ -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) }
|
||||
}));
|
||||
}
|
||||
}
|
||||
|
@ -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)
|
||||
|
Loading…
Reference in New Issue
Block a user