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;
|
||||
}
|
||||
|
||||
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) {
|
||||
return phoneNumber.isEmpty()
|
||||
? Utf8String()
|
||||
|
|
|
@ -66,6 +66,7 @@ struct File {
|
|||
Unavailable,
|
||||
FileType,
|
||||
FileSize,
|
||||
DateLimits,
|
||||
};
|
||||
FileLocation location;
|
||||
int size = 0;
|
||||
|
@ -568,6 +569,14 @@ MessagesSlice ParseMessagesSlice(
|
|||
const MTPVector<MTPChat> &chats,
|
||||
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 FormatDateTime(
|
||||
TimeId date,
|
||||
|
|
|
@ -931,7 +931,7 @@ void ApiWrap::requestMessagesCount(int localSplitIndex) {
|
|||
Expects(_chatProcess != nullptr);
|
||||
|
||||
const auto count = result.match(
|
||||
[](const MTPDmessages_messages &data) {
|
||||
[](const MTPDmessages_messages &data) {
|
||||
return data.vmessages.v.size();
|
||||
}, [](const MTPDmessages_messagesSlice &data) {
|
||||
return data.vcount.v;
|
||||
|
@ -944,15 +944,55 @@ void ApiWrap::requestMessagesCount(int localSplitIndex) {
|
|||
error("Unexpected messagesNotModified received.");
|
||||
return;
|
||||
}
|
||||
_chatProcess->info.messagesCountPerSplit[localSplitIndex] = count;
|
||||
if (localSplitIndex + 1 < _chatProcess->info.splits.size()) {
|
||||
requestMessagesCount(localSplitIndex + 1);
|
||||
} else if (_chatProcess->start(_chatProcess->info)) {
|
||||
requestMessagesSlice();
|
||||
const auto skipSplit = !Data::SingleMessageAfter(
|
||||
result,
|
||||
_settings->singlePeerFrom);
|
||||
if (skipSplit) {
|
||||
// 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) {
|
||||
const auto guard = gsl::finally([&] { _takeoutId = std::nullopt; });
|
||||
|
||||
|
@ -1200,6 +1240,12 @@ void ApiWrap::appendChatsSlice(
|
|||
void ApiWrap::requestMessagesSlice() {
|
||||
Expects(_chatProcess != nullptr);
|
||||
|
||||
const auto count = _chatProcess->info.messagesCountPerSplit[
|
||||
_chatProcess->localSplitIndex];
|
||||
if (!count) {
|
||||
loadMessagesFiles({});
|
||||
return;
|
||||
}
|
||||
requestChatMessages(
|
||||
_chatProcess->info.splits[_chatProcess->localSplitIndex],
|
||||
_chatProcess->largestIdPlusOne,
|
||||
|
@ -1308,6 +1354,10 @@ void ApiWrap::loadNextMessageFile() {
|
|||
for (auto &list = _chatProcess->slice->list
|
||||
; _chatProcess->fileIndex < list.size()
|
||||
; ++_chatProcess->fileIndex) {
|
||||
const auto &message = list[_chatProcess->fileIndex];
|
||||
if (Data::SkipMessageByDate(message, *_settings)) {
|
||||
continue;
|
||||
}
|
||||
const auto fileProgress = [=](FileProgress value) {
|
||||
return loadMessageFileProgress(value);
|
||||
};
|
||||
|
@ -1452,7 +1502,10 @@ bool ApiWrap::processFileLoad(
|
|||
}) : Type(0);
|
||||
|
||||
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;
|
||||
return true;
|
||||
} else if ((message ? message->file().size : file.size) >= limit) {
|
||||
|
|
|
@ -141,6 +141,8 @@ private:
|
|||
int splitIndex);
|
||||
|
||||
void requestMessagesCount(int localSplitIndex);
|
||||
void checkFirstMessageDate(int localSplitIndex, int count);
|
||||
void messagesCountLoaded(int localSplitIndex, int count);
|
||||
void requestMessagesSlice();
|
||||
void requestChatMessages(
|
||||
int splitIndex,
|
||||
|
|
|
@ -2279,6 +2279,9 @@ Result HtmlWriter::writeDialogSlice(const Data::MessagesSlice &data) {
|
|||
auto saved = std::optional<MessageInfo>();
|
||||
auto block = QByteArray();
|
||||
for (const auto &message : data.list) {
|
||||
if (Data::SkipMessageByDate(message, _settings)) {
|
||||
continue;
|
||||
}
|
||||
const auto newIndex = (_messagesCount / kMessagesInFile);
|
||||
if (oldIndex != newIndex) {
|
||||
if (const auto result = _chat->writeBlock(block); !result) {
|
||||
|
@ -2328,7 +2331,7 @@ Result HtmlWriter::writeDialogSlice(const Data::MessagesSlice &data) {
|
|||
if (saved) {
|
||||
_lastMessageInfo = std::make_unique<MessageInfo>(*saved);
|
||||
}
|
||||
return _chat->writeBlock(block);
|
||||
return block.isEmpty() ? Result::Success() : _chat->writeBlock(block);
|
||||
}
|
||||
|
||||
Result HtmlWriter::writeEmptySinglePeer() {
|
||||
|
@ -2345,7 +2348,7 @@ Result HtmlWriter::writeEmptySinglePeer() {
|
|||
--_dateMessageId,
|
||||
_dialog,
|
||||
_settings.path,
|
||||
"Empty chat"));
|
||||
"No exported messages"));
|
||||
}
|
||||
|
||||
Result HtmlWriter::writeDialogEnd() {
|
||||
|
|
|
@ -1010,13 +1010,16 @@ Result JsonWriter::writeDialogSlice(const Data::MessagesSlice &data) {
|
|||
|
||||
auto block = QByteArray();
|
||||
for (const auto &message : data.list) {
|
||||
if (Data::SkipMessageByDate(message, _settings)) {
|
||||
continue;
|
||||
}
|
||||
block.append(prepareArrayItemStart() + SerializeMessage(
|
||||
_context,
|
||||
message,
|
||||
data.peers,
|
||||
_environment.internalLinksDomain));
|
||||
}
|
||||
return _output->writeBlock(block);
|
||||
return block.isEmpty() ? Result::Success() : _output->writeBlock(block);
|
||||
}
|
||||
|
||||
Result JsonWriter::writeDialogEnd() {
|
||||
|
|
|
@ -830,14 +830,20 @@ Result TextWriter::writeDialogSlice(const Data::MessagesSlice &data) {
|
|||
Expects(_chat != nullptr);
|
||||
Expects(!data.list.empty());
|
||||
|
||||
_messagesCount += data.list.size();
|
||||
auto list = std::vector<QByteArray>();
|
||||
list.reserve(data.list.size());
|
||||
for (const auto &message : data.list) {
|
||||
if (Data::SkipMessageByDate(message, _settings)) {
|
||||
continue;
|
||||
}
|
||||
list.push_back(SerializeMessage(
|
||||
message,
|
||||
data.peers,
|
||||
_environment.internalLinksDomain));
|
||||
++_messagesCount;
|
||||
}
|
||||
if (list.empty()) {
|
||||
return Result::Success();
|
||||
}
|
||||
const auto full = _chat->empty()
|
||||
? JoinList(kLineBreak, list)
|
||||
|
|
|
@ -119,6 +119,9 @@ void ResolveSettings(Settings &settings) {
|
|||
} else {
|
||||
settings.forceSubPath = IsDefaultPath(settings.path);
|
||||
}
|
||||
if (!settings.onlySinglePeer()) {
|
||||
settings.singlePeerFrom = settings.singlePeerTill = 0;
|
||||
}
|
||||
}
|
||||
|
||||
PanelController::PanelController(not_null<ControllerWrap*> process)
|
||||
|
|
Loading…
Reference in New Issue