mirror of https://github.com/procxx/kepka.git
Add support for JSON single-chat export.
This commit is contained in:
parent
02586ebe4b
commit
1686eb394d
|
@ -2150,6 +2150,8 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|||
"lng_export_option_size_limit" = "Size limit: {size}";
|
||||
"lng_export_header_format" = "Location and format";
|
||||
"lng_export_option_location" = "Download path: {path}";
|
||||
"lng_export_option_format_location" = "Format: {format}, Path: {path}";
|
||||
"lng_export_option_choose_format" = "Choose export format";
|
||||
"lng_export_option_html" = "Human-readable HTML";
|
||||
"lng_export_option_json" = "Machine-readable JSON";
|
||||
"lng_export_limits" = "From: {from}, to: {till}";
|
||||
|
|
|
@ -24,7 +24,6 @@ Settings NormalizeSettings(const Settings &settings) {
|
|||
return base::duplicate(settings);
|
||||
}
|
||||
auto result = base::duplicate(settings);
|
||||
result.format = Output::Format::Html;
|
||||
result.types = result.fullChats = Settings::Type::AnyChatsMask;
|
||||
return result;
|
||||
}
|
||||
|
|
|
@ -630,7 +630,9 @@ Result JsonWriter::start(
|
|||
_environment = environment;
|
||||
_stats = stats;
|
||||
_output = fileWithRelativePath(mainFileRelativePath());
|
||||
|
||||
if (_settings.onlySinglePeer()) {
|
||||
return Result::Success();
|
||||
}
|
||||
auto block = pushNesting(Context::kObject);
|
||||
block.append(prepareObjectItemStart("about"));
|
||||
block.append(SerializeString(_environment.aboutTelegram));
|
||||
|
@ -993,9 +995,11 @@ Result JsonWriter::writeDialogsStart(const Data::DialogsInfo &data) {
|
|||
Result JsonWriter::writeDialogStart(const Data::DialogInfo &data) {
|
||||
Expects(_output != nullptr);
|
||||
|
||||
const auto result = validateDialogsMode(data.isLeftChannel);
|
||||
if (!result) {
|
||||
return result;
|
||||
if (!_settings.onlySinglePeer()) {
|
||||
const auto result = validateDialogsMode(data.isLeftChannel);
|
||||
if (!result) {
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
using Type = Data::DialogInfo::Type;
|
||||
|
@ -1014,7 +1018,9 @@ Result JsonWriter::writeDialogStart(const Data::DialogInfo &data) {
|
|||
Unexpected("Dialog type in TypeString.");
|
||||
};
|
||||
|
||||
auto block = prepareArrayItemStart();
|
||||
auto block = _settings.onlySinglePeer()
|
||||
? QByteArray()
|
||||
: prepareArrayItemStart();
|
||||
block.append(pushNesting(Context::kObject));
|
||||
if (data.type != Type::Self) {
|
||||
block.append(prepareObjectItemStart("name")
|
||||
|
@ -1073,6 +1079,9 @@ Result JsonWriter::writeDialogEnd() {
|
|||
}
|
||||
|
||||
Result JsonWriter::writeDialogsEnd() {
|
||||
if (_settings.onlySinglePeer()) {
|
||||
return Result::Success();
|
||||
}
|
||||
return writeChatsEnd();
|
||||
}
|
||||
|
||||
|
@ -1099,6 +1108,10 @@ Result JsonWriter::writeChatsEnd() {
|
|||
Result JsonWriter::finish() {
|
||||
Expects(_output != nullptr);
|
||||
|
||||
if (_settings.onlySinglePeer()) {
|
||||
Assert(_context.nesting.empty());
|
||||
return Result::Success();
|
||||
}
|
||||
auto block = popNesting();
|
||||
Assert(_context.nesting.empty());
|
||||
return _output->writeBlock(block);
|
||||
|
|
|
@ -19,6 +19,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|||
#include "ui/wrap/padding_wrap.h"
|
||||
#include "ui/wrap/slide_wrap.h"
|
||||
#include "ui/wrap/fade_wrap.h"
|
||||
#include "ui/layers/generic_box.h"
|
||||
#include "ui/text/text_utilities.h"
|
||||
#include "platform/platform_specific.h"
|
||||
#include "core/file_utilities.h"
|
||||
|
@ -35,7 +36,7 @@ namespace {
|
|||
|
||||
constexpr auto kMegabyte = 1024 * 1024;
|
||||
|
||||
PeerId ReadPeerId(const MTPInputPeer &data) {
|
||||
[[nodiscard]] PeerId ReadPeerId(const MTPInputPeer &data) {
|
||||
return data.match([](const MTPDinputPeerUser &data) {
|
||||
return peerFromUser(data.vuser_id().v);
|
||||
}, [](const MTPDinputPeerUserFromMessage &data) {
|
||||
|
@ -53,6 +54,29 @@ PeerId ReadPeerId(const MTPInputPeer &data) {
|
|||
});
|
||||
}
|
||||
|
||||
[[nodiscard]] void ChooseFormatBox(
|
||||
not_null<Ui::GenericBox*> box,
|
||||
Output::Format format,
|
||||
Fn<void(Output::Format)> done) {
|
||||
using Format = Output::Format;
|
||||
const auto group = std::make_shared<Ui::RadioenumGroup<Format>>(format);
|
||||
const auto addFormatOption = [&](QString label, Format format) {
|
||||
const auto radio = box->addRow(
|
||||
object_ptr<Ui::Radioenum<Format>>(
|
||||
box,
|
||||
group,
|
||||
format,
|
||||
label,
|
||||
st::defaultBoxCheckbox),
|
||||
st::exportSettingPadding);
|
||||
};
|
||||
box->setTitle(tr::lng_export_option_choose_format());
|
||||
addFormatOption(tr::lng_export_option_html(tr::now), Format::Html);
|
||||
addFormatOption(tr::lng_export_option_json(tr::now), Format::Json);
|
||||
box->addButton(tr::lng_settings_save(), [=] { done(group->value()); });
|
||||
box->addButton(tr::lng_cancel(), [=] { box->closeBox(); });
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
int SizeLimitByIndex(int index) {
|
||||
|
@ -221,7 +245,7 @@ void SettingsWidget::setupOtherOptions(
|
|||
void SettingsWidget::setupPathAndFormat(
|
||||
not_null<Ui::VerticalLayout*> container) {
|
||||
if (_singlePeerId != 0) {
|
||||
addLocationLabel(container);
|
||||
addFormatAndLocationLabel(container);
|
||||
addLimitsLabel(container);
|
||||
return;
|
||||
}
|
||||
|
@ -278,6 +302,72 @@ void SettingsWidget::addLocationLabel(
|
|||
#endif // OS_MAC_STORE
|
||||
}
|
||||
|
||||
void SettingsWidget::chooseFormat() {
|
||||
const auto shared = std::make_shared<QPointer<Ui::GenericBox>>();
|
||||
const auto callback = [=](Format format) {
|
||||
changeData([&](Settings &data) {
|
||||
data.format = format;
|
||||
});
|
||||
if (const auto weak = shared->data()) {
|
||||
weak->closeBox();
|
||||
}
|
||||
};
|
||||
auto box = Box(
|
||||
ChooseFormatBox,
|
||||
readData().format,
|
||||
callback);
|
||||
*shared = Ui::MakeWeak(box.data());
|
||||
_showBoxCallback(std::move(box));
|
||||
}
|
||||
|
||||
void SettingsWidget::addFormatAndLocationLabel(
|
||||
not_null<Ui::VerticalLayout*> container) {
|
||||
#ifndef OS_MAC_STORE
|
||||
auto pathLink = value() | rpl::map([](const Settings &data) {
|
||||
return data.path;
|
||||
}) | rpl::distinct_until_changed(
|
||||
) | rpl::map([](const QString &path) {
|
||||
const auto text = IsDefaultPath(path)
|
||||
? u"Downloads/Telegram Desktop"_q
|
||||
: path;
|
||||
return Ui::Text::Link(
|
||||
QDir::toNativeSeparators(text),
|
||||
u"internal:edit_export_path"_q);
|
||||
});
|
||||
auto formatLink = value() | rpl::map([](const Settings &data) {
|
||||
return data.format;
|
||||
}) | rpl::distinct_until_changed(
|
||||
) | rpl::map([](Format format) {
|
||||
const auto text = (format == Format::Html) ? "HTML" : "JSON";
|
||||
return Ui::Text::Link(text, u"internal:edit_format"_q);
|
||||
});
|
||||
const auto label = container->add(
|
||||
object_ptr<Ui::FlatLabel>(
|
||||
container,
|
||||
tr::lng_export_option_format_location(
|
||||
lt_format,
|
||||
std::move(formatLink),
|
||||
lt_path,
|
||||
std::move(pathLink),
|
||||
Ui::Text::WithEntities),
|
||||
st::exportLocationLabel),
|
||||
st::exportLocationPadding);
|
||||
label->setClickHandlerFilter([=](
|
||||
const ClickHandlerPtr &handler,
|
||||
Qt::MouseButton) {
|
||||
const auto url = handler->dragText();
|
||||
if (url == qstr("internal:edit_export_path")) {
|
||||
chooseFolder();
|
||||
} else if (url == qstr("internal:edit_format")) {
|
||||
chooseFormat();
|
||||
} else {
|
||||
Unexpected("Click handler URL in export limits edit.");
|
||||
}
|
||||
return false;
|
||||
});
|
||||
#endif // OS_MAC_STORE
|
||||
}
|
||||
|
||||
void SettingsWidget::addLimitsLabel(
|
||||
not_null<Ui::VerticalLayout*> container) {
|
||||
auto fromLink = value() | rpl::map([](const Settings &data) {
|
||||
|
@ -351,7 +441,6 @@ void SettingsWidget::addLimitsLabel(
|
|||
}
|
||||
return false;
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
void SettingsWidget::editDateLimit(
|
||||
|
|
|
@ -77,9 +77,12 @@ private:
|
|||
void addSizeSlider(not_null<Ui::VerticalLayout*> container);
|
||||
void addLocationLabel(
|
||||
not_null<Ui::VerticalLayout*> container);
|
||||
void addFormatAndLocationLabel(
|
||||
not_null<Ui::VerticalLayout*> container);
|
||||
void addLimitsLabel(
|
||||
not_null<Ui::VerticalLayout*> container);
|
||||
void chooseFolder();
|
||||
void chooseFormat();
|
||||
void refreshButtons(
|
||||
not_null<Ui::RpWidget*> container,
|
||||
bool canStart);
|
||||
|
|
Loading…
Reference in New Issue