mirror of https://github.com/procxx/kepka.git
Call finish takeout. Handle errors.
This commit is contained in:
parent
fcda883878
commit
36fb6dac89
|
@ -1697,6 +1697,8 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
"lng_export_total_files" = "Total files: {count}.";
|
"lng_export_total_files" = "Total files: {count}.";
|
||||||
"lng_export_total_size" = "Total size: {size}.";
|
"lng_export_total_size" = "Total size: {size}.";
|
||||||
"lng_export_folder" = "Choose export folder";
|
"lng_export_folder" = "Choose export folder";
|
||||||
|
"lng_export_invalid" = "Sorry, you have started a new data export, so this data export is now cancelled.";
|
||||||
|
"lng_export_delay" = "Sorry, for security reasons this data export will be available for you:\n\n{date}\n\nAt this time please try again.";
|
||||||
|
|
||||||
// Wnd specific
|
// Wnd specific
|
||||||
|
|
||||||
|
|
|
@ -1023,6 +1023,7 @@ invokeAfterMsgs#3dc4b4f0 {X:Type} msg_ids:Vector<long> query:!X = X;
|
||||||
initConnection#785188b8 {X:Type} flags:# api_id:int device_model:string system_version:string app_version:string system_lang_code:string lang_pack:string lang_code:string proxy:flags.0?InputClientProxy query:!X = X;
|
initConnection#785188b8 {X:Type} flags:# api_id:int device_model:string system_version:string app_version:string system_lang_code:string lang_pack:string lang_code:string proxy:flags.0?InputClientProxy query:!X = X;
|
||||||
invokeWithLayer#da9b0d0d {X:Type} layer:int query:!X = X;
|
invokeWithLayer#da9b0d0d {X:Type} layer:int query:!X = X;
|
||||||
invokeWithoutUpdates#bf9459b7 {X:Type} query:!X = X;
|
invokeWithoutUpdates#bf9459b7 {X:Type} query:!X = X;
|
||||||
|
invokeWithMessagesRange#365275f2 {X:Type} range:MessageRange query:!X = X;
|
||||||
invokeWithTakeout#aca9fd2e {X:Type} takeout_id:long query:!X = X;
|
invokeWithTakeout#aca9fd2e {X:Type} takeout_id:long query:!X = X;
|
||||||
|
|
||||||
auth.sendCode#86aef0ec flags:# allow_flashcall:flags.0?true phone_number:string current_number:flags.0?Bool api_id:int api_hash:string = auth.SentCode;
|
auth.sendCode#86aef0ec flags:# allow_flashcall:flags.0?true phone_number:string current_number:flags.0?Bool api_id:int api_hash:string = auth.SentCode;
|
||||||
|
@ -1082,6 +1083,7 @@ account.verifyPhone#4dd3a7f6 phone_number:string phone_code_hash:string phone_co
|
||||||
account.sendVerifyEmailCode#7011509f email:string = account.SentEmailCode;
|
account.sendVerifyEmailCode#7011509f email:string = account.SentEmailCode;
|
||||||
account.verifyEmail#ecba39db email:string code:string = Bool;
|
account.verifyEmail#ecba39db email:string code:string = Bool;
|
||||||
account.initTakeoutSession#f05b4804 flags:# contacts:flags.0?true message_users:flags.1?true message_chats:flags.2?true message_megagroups:flags.3?true message_channels:flags.4?true files:flags.5?true file_max_size:flags.5?int = account.Takeout;
|
account.initTakeoutSession#f05b4804 flags:# contacts:flags.0?true message_users:flags.1?true message_chats:flags.2?true message_megagroups:flags.3?true message_channels:flags.4?true files:flags.5?true file_max_size:flags.5?int = account.Takeout;
|
||||||
|
account.finishTakeoutSession#1d2652ee flags:# success:flags.0?true = Bool;
|
||||||
|
|
||||||
users.getUsers#d91a548 id:Vector<InputUser> = Vector<User>;
|
users.getUsers#d91a548 id:Vector<InputUser> = Vector<User>;
|
||||||
users.getFullUser#ca30a5b1 id:InputUser = UserFull;
|
users.getFullUser#ca30a5b1 id:InputUser = UserFull;
|
||||||
|
@ -1200,6 +1202,7 @@ messages.getRecentLocations#bbc45b09 peer:InputPeer limit:int hash:int = message
|
||||||
messages.sendMultiMedia#2095512f flags:# silent:flags.5?true background:flags.6?true clear_draft:flags.7?true peer:InputPeer reply_to_msg_id:flags.0?int multi_media:Vector<InputSingleMedia> = Updates;
|
messages.sendMultiMedia#2095512f flags:# silent:flags.5?true background:flags.6?true clear_draft:flags.7?true peer:InputPeer reply_to_msg_id:flags.0?int multi_media:Vector<InputSingleMedia> = Updates;
|
||||||
messages.uploadEncryptedFile#5057c497 peer:InputEncryptedChat file:InputEncryptedFile = EncryptedFile;
|
messages.uploadEncryptedFile#5057c497 peer:InputEncryptedChat file:InputEncryptedFile = EncryptedFile;
|
||||||
messages.searchStickerSets#c2b7d08b flags:# exclude_featured:flags.0?true q:string hash:int = messages.FoundStickerSets;
|
messages.searchStickerSets#c2b7d08b flags:# exclude_featured:flags.0?true q:string hash:int = messages.FoundStickerSets;
|
||||||
|
messages.getSplitRanges#1cff7e08 = Vector<MessageRange>;
|
||||||
|
|
||||||
updates.getState#edd4882a = updates.State;
|
updates.getState#edd4882a = updates.State;
|
||||||
updates.getDifference#25939651 flags:# pts:int pts_total_limit:flags.0?int date:int qts:int = updates.Difference;
|
updates.getDifference#25939651 flags:# pts:int pts_total_limit:flags.0?int date:int qts:int = updates.Difference;
|
||||||
|
|
|
@ -77,7 +77,7 @@ void Session::startExport() {
|
||||||
|
|
||||||
_exportViewChanges.fire(_exportPanel.get());
|
_exportViewChanges.fire(_exportPanel.get());
|
||||||
|
|
||||||
_exportPanel->closed(
|
_exportPanel->stopRequests(
|
||||||
) | rpl::start_with_next([=] {
|
) | rpl::start_with_next([=] {
|
||||||
stopExport();
|
stopExport();
|
||||||
}, _export->lifetime());
|
}, _export->lifetime());
|
||||||
|
|
|
@ -707,6 +707,23 @@ void ApiWrap::requestMessages(
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ApiWrap::finishExport(FnMut<void()> done) {
|
||||||
|
const auto guard = gsl::finally([&] { _takeoutId = base::none; });
|
||||||
|
|
||||||
|
mainRequest(MTPaccount_FinishTakeoutSession(
|
||||||
|
MTP_flags(MTPaccount_FinishTakeoutSession::Flag::f_success)
|
||||||
|
)).done(std::move(done)).send();
|
||||||
|
}
|
||||||
|
|
||||||
|
void ApiWrap::cancelExportFast() {
|
||||||
|
if (_takeoutId.has_value()) {
|
||||||
|
const auto requestId = mainRequest(MTPaccount_FinishTakeoutSession(
|
||||||
|
MTP_flags(0)
|
||||||
|
)).send();
|
||||||
|
_mtp.request(requestId).detach();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void ApiWrap::requestDialogsSlice() {
|
void ApiWrap::requestDialogsSlice() {
|
||||||
Expects(_dialogsProcess != nullptr);
|
Expects(_dialogsProcess != nullptr);
|
||||||
|
|
||||||
|
|
|
@ -81,6 +81,9 @@ public:
|
||||||
Fn<bool(Data::MessagesSlice&&)> slice,
|
Fn<bool(Data::MessagesSlice&&)> slice,
|
||||||
FnMut<void()> done);
|
FnMut<void()> done);
|
||||||
|
|
||||||
|
void finishExport(FnMut<void()> done);
|
||||||
|
void cancelExportFast();
|
||||||
|
|
||||||
~ApiWrap();
|
~ApiWrap();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
|
@ -33,6 +33,7 @@ public:
|
||||||
|
|
||||||
// Processing step.
|
// Processing step.
|
||||||
void startExport(const Settings &settings);
|
void startExport(const Settings &settings);
|
||||||
|
void cancelExportFast();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
using Step = ProcessingState::Step;
|
using Step = ProcessingState::Step;
|
||||||
|
@ -153,6 +154,9 @@ rpl::producer<State> Controller::state() const {
|
||||||
}
|
}
|
||||||
|
|
||||||
void Controller::setState(State &&state) {
|
void Controller::setState(State &&state) {
|
||||||
|
if (_state.is<CancelledState>()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
_state = std::move(state);
|
_state = std::move(state);
|
||||||
_stateChanges.fire_copy(_state);
|
_stateChanges.fire_copy(_state);
|
||||||
}
|
}
|
||||||
|
@ -326,6 +330,11 @@ void Controller::fillSubstepsInSteps(const ApiWrap::StartInfo &info) {
|
||||||
_substepsTotal = ranges::accumulate(_substepsInStep, 0);
|
_substepsTotal = ranges::accumulate(_substepsInStep, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Controller::cancelExportFast() {
|
||||||
|
_api.cancelExportFast();
|
||||||
|
setState(CancelledState());
|
||||||
|
}
|
||||||
|
|
||||||
void Controller::exportNext() {
|
void Controller::exportNext() {
|
||||||
if (!++_stepIndex) {
|
if (!++_stepIndex) {
|
||||||
if (ioCatchError(_writer->start(_settings, &_stats))) {
|
if (ioCatchError(_writer->start(_settings, &_stats))) {
|
||||||
|
@ -336,9 +345,12 @@ void Controller::exportNext() {
|
||||||
if (ioCatchError(_writer->finish())) {
|
if (ioCatchError(_writer->finish())) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
setFinishedState();
|
_api.finishExport([=] {
|
||||||
|
setFinishedState();
|
||||||
|
});
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const auto step = _steps[_stepIndex];
|
const auto step = _steps[_stepIndex];
|
||||||
switch (step) {
|
switch (step) {
|
||||||
case Step::Initializing: return initialize();
|
case Step::Initializing: return initialize();
|
||||||
|
@ -713,6 +725,14 @@ void ControllerWrap::startExport(const Settings &settings) {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ControllerWrap::cancelExportFast() {
|
||||||
|
LOG(("Export Info: Cancelled export."));
|
||||||
|
|
||||||
|
_wrapped.with([=](Controller &controller) {
|
||||||
|
controller.cancelExportFast();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
rpl::lifetime &ControllerWrap::lifetime() {
|
rpl::lifetime &ControllerWrap::lifetime() {
|
||||||
return _lifetime;
|
return _lifetime;
|
||||||
}
|
}
|
||||||
|
|
|
@ -74,6 +74,9 @@ struct OutputErrorState {
|
||||||
QString path;
|
QString path;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct CancelledState {
|
||||||
|
};
|
||||||
|
|
||||||
struct FinishedState {
|
struct FinishedState {
|
||||||
QString path;
|
QString path;
|
||||||
int filesCount = 0;
|
int filesCount = 0;
|
||||||
|
@ -85,6 +88,7 @@ using State = base::optional_variant<
|
||||||
ProcessingState,
|
ProcessingState,
|
||||||
ApiErrorState,
|
ApiErrorState,
|
||||||
OutputErrorState,
|
OutputErrorState,
|
||||||
|
CancelledState,
|
||||||
FinishedState>;
|
FinishedState>;
|
||||||
|
|
||||||
//struct PasswordUpdate {
|
//struct PasswordUpdate {
|
||||||
|
@ -113,6 +117,7 @@ public:
|
||||||
|
|
||||||
// Processing step.
|
// Processing step.
|
||||||
void startExport(const Settings &settings);
|
void startExport(const Settings &settings);
|
||||||
|
void cancelExportFast();
|
||||||
|
|
||||||
rpl::lifetime &lifetime();
|
rpl::lifetime &lifetime();
|
||||||
|
|
||||||
|
|
|
@ -20,6 +20,11 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
|
|
||||||
namespace Export {
|
namespace Export {
|
||||||
namespace View {
|
namespace View {
|
||||||
|
namespace {
|
||||||
|
|
||||||
|
constexpr auto kAddDelay = TimeId(60);
|
||||||
|
|
||||||
|
} // namespace
|
||||||
|
|
||||||
PanelController::PanelController(not_null<ControllerWrap*> process)
|
PanelController::PanelController(not_null<ControllerWrap*> process)
|
||||||
: _process(process) {
|
: _process(process) {
|
||||||
|
@ -64,17 +69,27 @@ void PanelController::showSettings() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void PanelController::showError(const ApiErrorState &error) {
|
void PanelController::showError(const ApiErrorState &error) {
|
||||||
showError("API Error happened :(\n"
|
if (error.data.type() == qstr("TAKEOUT_INVALID")) {
|
||||||
+ QString::number(error.data.code()) + ": " + error.data.type()
|
showError(lang(lng_export_invalid));
|
||||||
+ "\n" + error.data.description());
|
} else if (error.data.type().startsWith(qstr("TAKEOUT_INIT_DELAY_"))) {
|
||||||
|
const auto seconds = std::max(error.data.type().mid(
|
||||||
|
qstr("TAKEOUT_INIT_DELAY_").size()).toInt(), 0) + kAddDelay;
|
||||||
|
const auto now = QDateTime::currentDateTime();
|
||||||
|
const auto when = now.addSecs(seconds);
|
||||||
|
showError(lng_export_delay(lt_date, langDateTimeFull(when)));
|
||||||
|
} else {
|
||||||
|
showCriticalError("API Error happened :(\n"
|
||||||
|
+ QString::number(error.data.code()) + ": " + error.data.type()
|
||||||
|
+ "\n" + error.data.description());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void PanelController::showError(const OutputErrorState &error) {
|
void PanelController::showError(const OutputErrorState &error) {
|
||||||
showError("Disk Error happened :(\n"
|
showCriticalError("Disk Error happened :(\n"
|
||||||
"Could not write path:\n" + error.path);
|
"Could not write path:\n" + error.path);
|
||||||
}
|
}
|
||||||
|
|
||||||
void PanelController::showError(const QString &text) {
|
void PanelController::showCriticalError(const QString &text) {
|
||||||
auto container = base::make_unique_q<Ui::PaddingWrap<Ui::FlatLabel>>(
|
auto container = base::make_unique_q<Ui::PaddingWrap<Ui::FlatLabel>>(
|
||||||
_panel.get(),
|
_panel.get(),
|
||||||
object_ptr<Ui::FlatLabel>(
|
object_ptr<Ui::FlatLabel>(
|
||||||
|
@ -92,6 +107,26 @@ void PanelController::showError(const QString &text) {
|
||||||
_panel->setHideOnDeactivate(false);
|
_panel->setHideOnDeactivate(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void PanelController::showError(const QString &text) {
|
||||||
|
auto box = Box<InformBox>(text);
|
||||||
|
const auto weak = make_weak(box.data());
|
||||||
|
const auto hidden = _panel->isHidden();
|
||||||
|
_panel->showBox(
|
||||||
|
std::move(box),
|
||||||
|
LayerOption::CloseOther,
|
||||||
|
hidden ? anim::type::instant : anim::type::normal);
|
||||||
|
weak->setCloseByEscape(false);
|
||||||
|
weak->setCloseByOutsideClick(false);
|
||||||
|
weak->boxClosing(
|
||||||
|
) | rpl::start_with_next([=] {
|
||||||
|
_panel->hideGetDuration();
|
||||||
|
}, weak->lifetime());
|
||||||
|
if (hidden) {
|
||||||
|
_panel->showAndActivate();
|
||||||
|
}
|
||||||
|
_panel->setHideOnDeactivate(false);
|
||||||
|
}
|
||||||
|
|
||||||
void PanelController::showProgress() {
|
void PanelController::showProgress() {
|
||||||
_panel->setTitle(Lang::Viewer(lng_export_progress_title));
|
_panel->setTitle(Lang::Viewer(lng_export_progress_title));
|
||||||
|
|
||||||
|
@ -125,10 +160,11 @@ void PanelController::stopWithConfirmation(FnMut<void()> callback) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
auto stop = [=, callback = std::move(callback)]() mutable {
|
auto stop = [=, callback = std::move(callback)]() mutable {
|
||||||
auto saved = std::move(callback);
|
if (auto saved = std::move(callback)) {
|
||||||
stopExport();
|
stopExport();
|
||||||
if (saved) {
|
|
||||||
saved();
|
saved();
|
||||||
|
} else {
|
||||||
|
_process->cancelExportFast();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
const auto hidden = _panel->isHidden();
|
const auto hidden = _panel->isHidden();
|
||||||
|
@ -157,7 +193,7 @@ void PanelController::stopExport() {
|
||||||
_panel->hideGetDuration();
|
_panel->hideGetDuration();
|
||||||
}
|
}
|
||||||
|
|
||||||
rpl::producer<> PanelController::closed() const {
|
rpl::producer<> PanelController::stopRequests() const {
|
||||||
return _panelCloseEvents.events(
|
return _panelCloseEvents.events(
|
||||||
) | rpl::flatten_latest(
|
) | rpl::flatten_latest(
|
||||||
) | rpl::filter([=] {
|
) | rpl::filter([=] {
|
||||||
|
@ -174,9 +210,11 @@ void PanelController::updateState(State &&state) {
|
||||||
showError(*apiError);
|
showError(*apiError);
|
||||||
} else if (const auto error = base::get_if<OutputErrorState>(&_state)) {
|
} else if (const auto error = base::get_if<OutputErrorState>(&_state)) {
|
||||||
showError(*error);
|
showError(*error);
|
||||||
} else if (const auto finished = base::get_if<FinishedState>(&_state)) {
|
} else if (_state.is<FinishedState>()) {
|
||||||
_panel->setTitle(Lang::Viewer(lng_export_title));
|
_panel->setTitle(Lang::Viewer(lng_export_title));
|
||||||
_panel->setHideOnDeactivate(false);
|
_panel->setHideOnDeactivate(false);
|
||||||
|
} else if (_state.is<CancelledState>()) {
|
||||||
|
stopExport();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -29,7 +29,7 @@ public:
|
||||||
void activatePanel();
|
void activatePanel();
|
||||||
void stopWithConfirmation(FnMut<void()> callback = nullptr);
|
void stopWithConfirmation(FnMut<void()> callback = nullptr);
|
||||||
|
|
||||||
rpl::producer<> closed() const;
|
rpl::producer<> stopRequests() const;
|
||||||
|
|
||||||
rpl::lifetime &lifetime() {
|
rpl::lifetime &lifetime() {
|
||||||
return _lifetime;
|
return _lifetime;
|
||||||
|
@ -50,6 +50,7 @@ private:
|
||||||
void showError(const ApiErrorState &error);
|
void showError(const ApiErrorState &error);
|
||||||
void showError(const OutputErrorState &error);
|
void showError(const OutputErrorState &error);
|
||||||
void showError(const QString &text);
|
void showError(const QString &text);
|
||||||
|
void showCriticalError(const QString &text);
|
||||||
|
|
||||||
not_null<ControllerWrap*> _process;
|
not_null<ControllerWrap*> _process;
|
||||||
|
|
||||||
|
|
|
@ -198,7 +198,7 @@ void ConcurrentSender::senderRequestFail(
|
||||||
}
|
}
|
||||||
|
|
||||||
void ConcurrentSender::senderRequestCancel(mtpRequestId requestId) {
|
void ConcurrentSender::senderRequestCancel(mtpRequestId requestId) {
|
||||||
_requests.erase(requestId);
|
senderRequestDetach(requestId);
|
||||||
with_instance([=](not_null<Instance*> instance) {
|
with_instance([=](not_null<Instance*> instance) {
|
||||||
instance->cancel(requestId);
|
instance->cancel(requestId);
|
||||||
});
|
});
|
||||||
|
@ -216,4 +216,8 @@ void ConcurrentSender::senderRequestCancelAll() {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ConcurrentSender::senderRequestDetach(mtpRequestId requestId) {
|
||||||
|
_requests.erase(requestId);
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace MTP
|
} // namespace MTP
|
||||||
|
|
|
@ -148,6 +148,7 @@ public:
|
||||||
class SentRequestWrap {
|
class SentRequestWrap {
|
||||||
public:
|
public:
|
||||||
void cancel();
|
void cancel();
|
||||||
|
void detach();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
friend class ConcurrentSender;
|
friend class ConcurrentSender;
|
||||||
|
@ -190,6 +191,7 @@ private:
|
||||||
RPCError &&error);
|
RPCError &&error);
|
||||||
void senderRequestCancel(mtpRequestId requestId);
|
void senderRequestCancel(mtpRequestId requestId);
|
||||||
void senderRequestCancelAll();
|
void senderRequestCancelAll();
|
||||||
|
void senderRequestDetach(mtpRequestId requestId);
|
||||||
|
|
||||||
const Fn<void(FnMut<void()>)> _runner;
|
const Fn<void(FnMut<void()>)> _runner;
|
||||||
base::flat_map<mtpRequestId, Handlers> _requests;
|
base::flat_map<mtpRequestId, Handlers> _requests;
|
||||||
|
@ -446,6 +448,10 @@ inline void ConcurrentSender::SentRequestWrap::cancel() {
|
||||||
_sender->senderRequestCancel(_requestId);
|
_sender->senderRequestCancel(_requestId);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline void ConcurrentSender::SentRequestWrap::detach() {
|
||||||
|
_sender->senderRequestDetach(_requestId);
|
||||||
|
}
|
||||||
|
|
||||||
inline ConcurrentSender::SentRequestWrap::SentRequestWrap(
|
inline ConcurrentSender::SentRequestWrap::SentRequestWrap(
|
||||||
not_null<ConcurrentSender*> sender,
|
not_null<ConcurrentSender*> sender,
|
||||||
mtpRequestId requestId
|
mtpRequestId requestId
|
||||||
|
|
Loading…
Reference in New Issue