Add export statistics for the final screen.

This commit is contained in:
John Preston 2018-06-20 17:10:38 +01:00
parent e8dd277a00
commit e11c27048b
13 changed files with 116 additions and 18 deletions

View File

@ -1690,11 +1690,11 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
"lng_export_progress" = "Note: Please don't close Telegram while exporting files and personal data.";
"lng_export_stop" = "Stop";
"lng_export_sure_stop" = "Are you sure you want to stop exporting your data?\n\nThis action cannot be undone.";
"lng_export_about_done" = "Your data is successfully exported.";
"lng_export_about_done" = "Your data was successfully exported.";
"lng_export_done" = "Show my data";
"lng_export_finished" = "Export is finished.";
"lng_export_total_files" = "Total files: {count}";
"lng_export_total_size" = "Total size: {size}";
"lng_export_total_files" = "Total files: {count}.";
"lng_export_total_size" = "Total size: {size}.";
// Wnd specific

View File

@ -135,7 +135,7 @@ struct ApiWrap::UserpicsProcess {
};
struct ApiWrap::FileProcess {
FileProcess(const QString &path);
FileProcess(const QString &path, Output::Stats *stats);
Output::File file;
QString relativePath;
@ -222,7 +222,8 @@ base::optional<QString> ApiWrap::LoadedFileCache::find(
return base::none;
}
ApiWrap::FileProcess::FileProcess(const QString &path) : file(path) {
ApiWrap::FileProcess::FileProcess(const QString &path, Output::Stats *stats)
: file(path, stats) {
}
template <typename Request>
@ -267,11 +268,13 @@ rpl::producer<Output::Result> ApiWrap::ioErrors() const {
void ApiWrap::startExport(
const Settings &settings,
Output::Stats *stats,
FnMut<void(StartInfo)> done) {
Expects(_settings == nullptr);
Expects(_startProcess == nullptr);
_settings = std::make_unique<Settings>(settings);
_stats = stats;
_startProcess = std::make_unique<StartProcess>();
_startProcess->done = std::move(done);
@ -1079,7 +1082,8 @@ auto ApiWrap::prepareFileProcess(const Data::File &file) const
_settings->path,
file.suggestedPath);
auto result = std::make_unique<FileProcess>(
_settings->path + relativePath);
_settings->path + relativePath,
_stats);
result->relativePath = relativePath;
result->location = file.location;
result->size = file.size;

View File

@ -27,13 +27,14 @@ struct Message;
namespace Output {
struct Result;
class Stats;
} // namespace Output
struct Settings;
class ApiWrap {
public:
ApiWrap(Fn<void(FnMut<void()>)> runner);
explicit ApiWrap(Fn<void(FnMut<void()>)> runner);
rpl::producer<RPCError> errors() const;
rpl::producer<Output::Result> ioErrors() const;
@ -45,6 +46,7 @@ public:
};
void startExport(
const Settings &settings,
Output::Stats *stats,
FnMut<void(StartInfo)> done);
void requestLeftChannelsList(
@ -155,6 +157,7 @@ private:
MTP::ConcurrentSender _mtp;
base::optional<uint64> _takeoutId;
Output::Stats *_stats = nullptr;
std::unique_ptr<Settings> _settings;
MTPInputUser _user = MTP_inputUserSelf();

View File

@ -12,6 +12,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "export/data/export_data_types.h"
#include "export/output/export_output_abstract.h"
#include "export/output/export_output_result.h"
#include "export/output/export_output_stats.h"
namespace Export {
@ -102,6 +103,9 @@ private:
// rpl::variable<State> fails to compile in MSVC :(
State _state;
rpl::event_stream<State> _stateChanges;
Output::Stats _stats;
std::vector<int> _substepsInStep;
int _substepsTotal = 0;
mutable int _substepsPassed = 0;
@ -321,7 +325,7 @@ void Controller::fillSubstepsInSteps(const ApiWrap::StartInfo &info) {
void Controller::exportNext() {
if (!++_stepIndex) {
if (ioCatchError(_writer->start(_settings))) {
if (ioCatchError(_writer->start(_settings, &_stats))) {
return;
}
}
@ -350,7 +354,7 @@ void Controller::exportNext() {
void Controller::initialize() {
setState(stateInitializing());
_api.startExport(_settings, [=](ApiWrap::StartInfo info) {
_api.startExport(_settings, &_stats, [=](ApiWrap::StartInfo info) {
fillSubstepsInSteps(info);
exportNext();
});
@ -642,7 +646,10 @@ int Controller::substepsInStep(Step step) const {
}
void Controller::setFinishedState() {
setState(FinishedState{ _writer->mainFilePath() });
setState(FinishedState{
_writer->mainFilePath(),
_stats.filesCount(),
_stats.bytesCount() });
}
ControllerWrap::ControllerWrap() {

View File

@ -22,6 +22,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include <vector>
#include <map>
#include <deque>
#include <atomic>
#include <range/v3/all.hpp>
#ifdef Q_OS_WIN

View File

@ -26,6 +26,7 @@ struct Settings;
namespace Output {
struct Result;
class Stats;
enum class Format {
Text,
@ -36,7 +37,9 @@ enum class Format {
class AbstractWriter {
public:
[[nodiscard]] virtual Result start(const Settings &settings) = 0;
[[nodiscard]] virtual Result start(
const Settings &settings,
Stats *stats) = 0;
[[nodiscard]] virtual Result writePersonal(
const Data::PersonalInfo &data) = 0;

View File

@ -8,6 +8,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "export/output/export_output_file.h"
#include "export/output/export_output_result.h"
#include "export/output/export_output_stats.h"
#include <QtCore/QFileInfo>
#include <QtCore/QDir>
@ -17,7 +18,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
namespace Export {
namespace Output {
File::File(const QString &path) : _path(path) {
File::File(const QString &path, Stats *stats) : _path(path), _stats(stats) {
}
int File::size() const {
@ -37,11 +38,22 @@ Result File::writeBlock(const QByteArray &block) {
}
Result File::writeBlockAttempt(const QByteArray &block) {
if (_stats && !_inStats) {
_inStats = true;
_stats->incrementFiles();
}
if (const auto result = reopen(); !result) {
return result;
}
if (_file->write(block) == block.size() && _file->flush()) {
_offset += block.size();
const auto size = block.size();
if (!size) {
return Result::Success();
}
if (_file->write(block) == size && _file->flush()) {
_offset += size;
if (_stats) {
_stats->incrementBytes(size);
}
return Result::Success();
}
return error();

View File

@ -17,10 +17,11 @@ namespace Export {
namespace Output {
struct Result;
class Stats;
class File {
public:
File(const QString &path);
File(const QString &path, Stats *stats);
[[nodiscard]] int size() const;
[[nodiscard]] bool empty() const;
@ -42,6 +43,9 @@ private:
int _offset = 0;
base::optional<QFile> _file;
Stats *_stats = nullptr;
bool _inStats = false;
};
} // namespace Output

View File

@ -0,0 +1,30 @@
/*
This file is part of Telegram Desktop,
the official desktop application for the Telegram messaging service.
For license and copyright information please follow this link:
https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
*/
#include "export/output/export_output_stats.h"
namespace Export {
namespace Output {
void Stats::incrementFiles() {
++_files;
}
void Stats::incrementBytes(int count) {
_bytes += count;
}
int Stats::filesCount() const {
return _files;
}
int64 Stats::bytesCount() const {
return _bytes;
}
} // namespace Output
} // namespace Export

View File

@ -0,0 +1,30 @@
/*
This file is part of Telegram Desktop,
the official desktop application for the Telegram messaging service.
For license and copyright information please follow this link:
https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
*/
#pragma once
#include <atomic>
namespace Export {
namespace Output {
class Stats {
public:
void incrementFiles();
void incrementBytes(int count);
int filesCount() const;
int64 bytesCount() const;
private:
std::atomic<int> _files;
std::atomic<int64> _bytes;
};
} // namespace Output
} // namespace Export

View File

@ -432,10 +432,11 @@ QByteArray SerializeMessage(
} // namespace
Result TextWriter::start(const Settings &settings) {
Result TextWriter::start(const Settings &settings, Stats *stats) {
Expects(settings.path.endsWith('/'));
_settings = base::duplicate(settings);
_stats = stats;
_summary = fileWithRelativePath(mainFileRelativePath());
return Result::Success();
}
@ -827,7 +828,7 @@ QString TextWriter::pathWithRelativePath(const QString &path) const {
std::unique_ptr<File> TextWriter::fileWithRelativePath(
const QString &path) const {
return std::make_unique<File>(pathWithRelativePath(path));
return std::make_unique<File>(pathWithRelativePath(path), _stats);
}
} // namespace Output

View File

@ -16,7 +16,7 @@ namespace Output {
class TextWriter : public AbstractWriter {
public:
Result start(const Settings &settings) override;
Result start(const Settings &settings, Stats *stats) override;
Result writePersonal(const Data::PersonalInfo &data) override;
@ -61,6 +61,7 @@ private:
Result writeChatEnd();
Settings _settings;
Stats *_stats = nullptr;
std::unique_ptr<File> _summary;
int _userpicsCount = 0;

View File

@ -61,6 +61,8 @@
'<(src_loc)/export/output/export_output_abstract.h',
'<(src_loc)/export/output/export_output_file.cpp',
'<(src_loc)/export/output/export_output_file.h',
'<(src_loc)/export/output/export_output_stats.cpp',
'<(src_loc)/export/output/export_output_stats.h',
'<(src_loc)/export/output/export_output_text.cpp',
'<(src_loc)/export/output/export_output_text.h',
],