mirror of https://github.com/procxx/kepka.git
Limit single chat export by dates.
This commit is contained in:
parent
f362702856
commit
841abc2e87
|
@ -1569,6 +1569,44 @@ MessagesSlice ParseMessagesSlice(
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TimeId SingleMessageDate(const MTPmessages_Messages &data) {
|
||||||
|
return data.match([&](const MTPDmessages_messagesNotModified &data) {
|
||||||
|
return 0;
|
||||||
|
}, [&](const auto &data) {
|
||||||
|
const auto &list = data.vmessages.v;
|
||||||
|
if (list.isEmpty()) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return list[0].match([](const MTPDmessageEmpty &data) {
|
||||||
|
return 0;
|
||||||
|
}, [](const auto &data) {
|
||||||
|
return data.vdate.v;
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
bool SingleMessageBefore(
|
||||||
|
const MTPmessages_Messages &data,
|
||||||
|
TimeId date) {
|
||||||
|
const auto single = SingleMessageDate(data);
|
||||||
|
return (single > 0 && single < date);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool SingleMessageAfter(
|
||||||
|
const MTPmessages_Messages &data,
|
||||||
|
TimeId date) {
|
||||||
|
const auto single = SingleMessageDate(data);
|
||||||
|
return (single > 0 && single > date);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool SkipMessageByDate(const Message &message, const Settings &settings) {
|
||||||
|
const auto goodFrom = (settings.singlePeerFrom <= 0)
|
||||||
|
|| (settings.singlePeerFrom <= message.date);
|
||||||
|
const auto goodTill = (settings.singlePeerTill <= 0)
|
||||||
|
|| (message.date < settings.singlePeerTill);
|
||||||
|
return !goodFrom || !goodTill;
|
||||||
|
}
|
||||||
|
|
||||||
Utf8String FormatPhoneNumber(const Utf8String &phoneNumber) {
|
Utf8String FormatPhoneNumber(const Utf8String &phoneNumber) {
|
||||||
return phoneNumber.isEmpty()
|
return phoneNumber.isEmpty()
|
||||||
? Utf8String()
|
? Utf8String()
|
||||||
|
|
|
@ -66,6 +66,7 @@ struct File {
|
||||||
Unavailable,
|
Unavailable,
|
||||||
FileType,
|
FileType,
|
||||||
FileSize,
|
FileSize,
|
||||||
|
DateLimits,
|
||||||
};
|
};
|
||||||
FileLocation location;
|
FileLocation location;
|
||||||
int size = 0;
|
int size = 0;
|
||||||
|
@ -568,6 +569,14 @@ MessagesSlice ParseMessagesSlice(
|
||||||
const MTPVector<MTPChat> &chats,
|
const MTPVector<MTPChat> &chats,
|
||||||
const QString &mediaFolder);
|
const QString &mediaFolder);
|
||||||
|
|
||||||
|
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 FormatPhoneNumber(const Utf8String &phoneNumber);
|
||||||
Utf8String FormatDateTime(
|
Utf8String FormatDateTime(
|
||||||
TimeId date,
|
TimeId date,
|
||||||
|
|
|
@ -931,7 +931,7 @@ void ApiWrap::requestMessagesCount(int localSplitIndex) {
|
||||||
Expects(_chatProcess != nullptr);
|
Expects(_chatProcess != nullptr);
|
||||||
|
|
||||||
const auto count = result.match(
|
const auto count = result.match(
|
||||||
[](const MTPDmessages_messages &data) {
|
[](const MTPDmessages_messages &data) {
|
||||||
return data.vmessages.v.size();
|
return data.vmessages.v.size();
|
||||||
}, [](const MTPDmessages_messagesSlice &data) {
|
}, [](const MTPDmessages_messagesSlice &data) {
|
||||||
return data.vcount.v;
|
return data.vcount.v;
|
||||||
|
@ -944,15 +944,55 @@ void ApiWrap::requestMessagesCount(int localSplitIndex) {
|
||||||
error("Unexpected messagesNotModified received.");
|
error("Unexpected messagesNotModified received.");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
_chatProcess->info.messagesCountPerSplit[localSplitIndex] = count;
|
const auto skipSplit = !Data::SingleMessageAfter(
|
||||||
if (localSplitIndex + 1 < _chatProcess->info.splits.size()) {
|
result,
|
||||||
requestMessagesCount(localSplitIndex + 1);
|
_settings->singlePeerFrom);
|
||||||
} else if (_chatProcess->start(_chatProcess->info)) {
|
if (skipSplit) {
|
||||||
requestMessagesSlice();
|
// No messages from the requested range, skip this split.
|
||||||
|
messagesCountLoaded(localSplitIndex, 0);
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
checkFirstMessageDate(localSplitIndex, count);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ApiWrap::checkFirstMessageDate(int localSplitIndex, int count) {
|
||||||
|
Expects(_chatProcess != nullptr);
|
||||||
|
Expects(localSplitIndex < _chatProcess->info.splits.size());
|
||||||
|
|
||||||
|
if (_settings->singlePeerTill <= 0) {
|
||||||
|
messagesCountLoaded(localSplitIndex, count);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Request first message in this split to check if its' date < till.
|
||||||
|
requestChatMessages(
|
||||||
|
_chatProcess->info.splits[localSplitIndex],
|
||||||
|
1, // offset_id
|
||||||
|
-1, // add_offset
|
||||||
|
1, // limit
|
||||||
|
[=](const MTPmessages_Messages &result) {
|
||||||
|
Expects(_chatProcess != nullptr);
|
||||||
|
|
||||||
|
const auto skipSplit = !Data::SingleMessageBefore(
|
||||||
|
result,
|
||||||
|
_settings->singlePeerTill);
|
||||||
|
messagesCountLoaded(localSplitIndex, skipSplit ? 0 : count);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
void ApiWrap::messagesCountLoaded(int localSplitIndex, int count) {
|
||||||
|
Expects(_chatProcess != nullptr);
|
||||||
|
Expects(localSplitIndex < _chatProcess->info.splits.size());
|
||||||
|
|
||||||
|
_chatProcess->info.messagesCountPerSplit[localSplitIndex] = count;
|
||||||
|
if (localSplitIndex + 1 < _chatProcess->info.splits.size()) {
|
||||||
|
requestMessagesCount(localSplitIndex + 1);
|
||||||
|
} else if (_chatProcess->start(_chatProcess->info)) {
|
||||||
|
requestMessagesSlice();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void ApiWrap::finishExport(FnMut<void()> done) {
|
void ApiWrap::finishExport(FnMut<void()> done) {
|
||||||
const auto guard = gsl::finally([&] { _takeoutId = std::nullopt; });
|
const auto guard = gsl::finally([&] { _takeoutId = std::nullopt; });
|
||||||
|
|
||||||
|
@ -1200,6 +1240,12 @@ void ApiWrap::appendChatsSlice(
|
||||||
void ApiWrap::requestMessagesSlice() {
|
void ApiWrap::requestMessagesSlice() {
|
||||||
Expects(_chatProcess != nullptr);
|
Expects(_chatProcess != nullptr);
|
||||||
|
|
||||||
|
const auto count = _chatProcess->info.messagesCountPerSplit[
|
||||||
|
_chatProcess->localSplitIndex];
|
||||||
|
if (!count) {
|
||||||
|
loadMessagesFiles({});
|
||||||
|
return;
|
||||||
|
}
|
||||||
requestChatMessages(
|
requestChatMessages(
|
||||||
_chatProcess->info.splits[_chatProcess->localSplitIndex],
|
_chatProcess->info.splits[_chatProcess->localSplitIndex],
|
||||||
_chatProcess->largestIdPlusOne,
|
_chatProcess->largestIdPlusOne,
|
||||||
|
@ -1308,6 +1354,10 @@ void ApiWrap::loadNextMessageFile() {
|
||||||
for (auto &list = _chatProcess->slice->list
|
for (auto &list = _chatProcess->slice->list
|
||||||
; _chatProcess->fileIndex < list.size()
|
; _chatProcess->fileIndex < list.size()
|
||||||
; ++_chatProcess->fileIndex) {
|
; ++_chatProcess->fileIndex) {
|
||||||
|
const auto &message = list[_chatProcess->fileIndex];
|
||||||
|
if (Data::SkipMessageByDate(message, *_settings)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
const auto fileProgress = [=](FileProgress value) {
|
const auto fileProgress = [=](FileProgress value) {
|
||||||
return loadMessageFileProgress(value);
|
return loadMessageFileProgress(value);
|
||||||
};
|
};
|
||||||
|
@ -1452,7 +1502,10 @@ bool ApiWrap::processFileLoad(
|
||||||
}) : Type(0);
|
}) : Type(0);
|
||||||
|
|
||||||
const auto limit = _settings->media.sizeLimit;
|
const auto limit = _settings->media.sizeLimit;
|
||||||
if ((_settings->media.types & type) != type) {
|
if (message && Data::SkipMessageByDate(*message, *_settings)) {
|
||||||
|
file.skipReason = SkipReason::DateLimits;
|
||||||
|
return true;
|
||||||
|
} else if ((_settings->media.types & type) != type) {
|
||||||
file.skipReason = SkipReason::FileType;
|
file.skipReason = SkipReason::FileType;
|
||||||
return true;
|
return true;
|
||||||
} else if ((message ? message->file().size : file.size) >= limit) {
|
} else if ((message ? message->file().size : file.size) >= limit) {
|
||||||
|
|
|
@ -141,6 +141,8 @@ private:
|
||||||
int splitIndex);
|
int splitIndex);
|
||||||
|
|
||||||
void requestMessagesCount(int localSplitIndex);
|
void requestMessagesCount(int localSplitIndex);
|
||||||
|
void checkFirstMessageDate(int localSplitIndex, int count);
|
||||||
|
void messagesCountLoaded(int localSplitIndex, int count);
|
||||||
void requestMessagesSlice();
|
void requestMessagesSlice();
|
||||||
void requestChatMessages(
|
void requestChatMessages(
|
||||||
int splitIndex,
|
int splitIndex,
|
||||||
|
|
|
@ -2279,6 +2279,9 @@ Result HtmlWriter::writeDialogSlice(const Data::MessagesSlice &data) {
|
||||||
auto saved = std::optional<MessageInfo>();
|
auto saved = std::optional<MessageInfo>();
|
||||||
auto block = QByteArray();
|
auto block = QByteArray();
|
||||||
for (const auto &message : data.list) {
|
for (const auto &message : data.list) {
|
||||||
|
if (Data::SkipMessageByDate(message, _settings)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
const auto newIndex = (_messagesCount / kMessagesInFile);
|
const auto newIndex = (_messagesCount / kMessagesInFile);
|
||||||
if (oldIndex != newIndex) {
|
if (oldIndex != newIndex) {
|
||||||
if (const auto result = _chat->writeBlock(block); !result) {
|
if (const auto result = _chat->writeBlock(block); !result) {
|
||||||
|
@ -2328,7 +2331,7 @@ Result HtmlWriter::writeDialogSlice(const Data::MessagesSlice &data) {
|
||||||
if (saved) {
|
if (saved) {
|
||||||
_lastMessageInfo = std::make_unique<MessageInfo>(*saved);
|
_lastMessageInfo = std::make_unique<MessageInfo>(*saved);
|
||||||
}
|
}
|
||||||
return _chat->writeBlock(block);
|
return block.isEmpty() ? Result::Success() : _chat->writeBlock(block);
|
||||||
}
|
}
|
||||||
|
|
||||||
Result HtmlWriter::writeEmptySinglePeer() {
|
Result HtmlWriter::writeEmptySinglePeer() {
|
||||||
|
@ -2345,7 +2348,7 @@ Result HtmlWriter::writeEmptySinglePeer() {
|
||||||
--_dateMessageId,
|
--_dateMessageId,
|
||||||
_dialog,
|
_dialog,
|
||||||
_settings.path,
|
_settings.path,
|
||||||
"Empty chat"));
|
"No exported messages"));
|
||||||
}
|
}
|
||||||
|
|
||||||
Result HtmlWriter::writeDialogEnd() {
|
Result HtmlWriter::writeDialogEnd() {
|
||||||
|
|
|
@ -1010,13 +1010,16 @@ Result JsonWriter::writeDialogSlice(const Data::MessagesSlice &data) {
|
||||||
|
|
||||||
auto block = QByteArray();
|
auto block = QByteArray();
|
||||||
for (const auto &message : data.list) {
|
for (const auto &message : data.list) {
|
||||||
|
if (Data::SkipMessageByDate(message, _settings)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
block.append(prepareArrayItemStart() + SerializeMessage(
|
block.append(prepareArrayItemStart() + SerializeMessage(
|
||||||
_context,
|
_context,
|
||||||
message,
|
message,
|
||||||
data.peers,
|
data.peers,
|
||||||
_environment.internalLinksDomain));
|
_environment.internalLinksDomain));
|
||||||
}
|
}
|
||||||
return _output->writeBlock(block);
|
return block.isEmpty() ? Result::Success() : _output->writeBlock(block);
|
||||||
}
|
}
|
||||||
|
|
||||||
Result JsonWriter::writeDialogEnd() {
|
Result JsonWriter::writeDialogEnd() {
|
||||||
|
|
|
@ -830,14 +830,20 @@ Result TextWriter::writeDialogSlice(const Data::MessagesSlice &data) {
|
||||||
Expects(_chat != nullptr);
|
Expects(_chat != nullptr);
|
||||||
Expects(!data.list.empty());
|
Expects(!data.list.empty());
|
||||||
|
|
||||||
_messagesCount += data.list.size();
|
|
||||||
auto list = std::vector<QByteArray>();
|
auto list = std::vector<QByteArray>();
|
||||||
list.reserve(data.list.size());
|
list.reserve(data.list.size());
|
||||||
for (const auto &message : data.list) {
|
for (const auto &message : data.list) {
|
||||||
|
if (Data::SkipMessageByDate(message, _settings)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
list.push_back(SerializeMessage(
|
list.push_back(SerializeMessage(
|
||||||
message,
|
message,
|
||||||
data.peers,
|
data.peers,
|
||||||
_environment.internalLinksDomain));
|
_environment.internalLinksDomain));
|
||||||
|
++_messagesCount;
|
||||||
|
}
|
||||||
|
if (list.empty()) {
|
||||||
|
return Result::Success();
|
||||||
}
|
}
|
||||||
const auto full = _chat->empty()
|
const auto full = _chat->empty()
|
||||||
? JoinList(kLineBreak, list)
|
? JoinList(kLineBreak, list)
|
||||||
|
|
|
@ -119,6 +119,9 @@ void ResolveSettings(Settings &settings) {
|
||||||
} else {
|
} else {
|
||||||
settings.forceSubPath = IsDefaultPath(settings.path);
|
settings.forceSubPath = IsDefaultPath(settings.path);
|
||||||
}
|
}
|
||||||
|
if (!settings.onlySinglePeer()) {
|
||||||
|
settings.singlePeerFrom = settings.singlePeerTill = 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
PanelController::PanelController(not_null<ControllerWrap*> process)
|
PanelController::PanelController(not_null<ControllerWrap*> process)
|
||||||
|
|
Loading…
Reference in New Issue