Skip to content

Commit

Permalink
Export sessions list.
Browse files Browse the repository at this point in the history
  • Loading branch information
john-preston committed Jun 11, 2018
1 parent cec8114 commit d3fdf43
Show file tree
Hide file tree
Showing 6 changed files with 114 additions and 29 deletions.
61 changes: 53 additions & 8 deletions Telegram/SourceFiles/export/data/export_data_types.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -100,19 +100,18 @@ Photo ParsePhoto(const MTPPhoto &data, const QString &suggestedPath) {
}

Utf8String FormatDateTime(
const int32 date,
const QDateTime &date,
QChar dateSeparator,
QChar timeSeparator,
QChar separator) {
const auto value = QDateTime::fromTime_t(date);
return (QString("%1") + dateSeparator + "%2" + dateSeparator + "%3"
+ separator + "%4" + timeSeparator + "%5" + timeSeparator + "%6"
).arg(value.date().year()
).arg(value.date().month(), 2, 10, QChar('0')
).arg(value.date().day(), 2, 10, QChar('0')
).arg(value.time().hour(), 2, 10, QChar('0')
).arg(value.time().minute(), 2, 10, QChar('0')
).arg(value.time().second(), 2, 10, QChar('0')
).arg(date.date().year()
).arg(date.date().month(), 2, 10, QChar('0')
).arg(date.date().day(), 2, 10, QChar('0')
).arg(date.time().hour(), 2, 10, QChar('0')
).arg(date.time().minute(), 2, 10, QChar('0')
).arg(date.time().second(), 2, 10, QChar('0')
).toUtf8();
}

Expand Down Expand Up @@ -200,6 +199,52 @@ ContactsList ParseContactsList(const MTPcontacts_Contacts &data) {
return result;
}

std::vector<int> SortedContactsIndices(const ContactsList &data) {
const auto names = ranges::view::all(
data.list
) | ranges::view::transform([](const Data::User &user) {
return (QString::fromUtf8(user.firstName)
+ ' '
+ QString::fromUtf8(user.lastName)).toLower();
}) | ranges::to_vector;

auto indices = ranges::view::ints(0, int(data.list.size()))
| ranges::to_vector;
ranges::sort(indices, [&](int i, int j) {
return names[i] < names[j];
});
return indices;
}

Session ParseSession(const MTPAuthorization &data) {
Expects(data.type() == mtpc_authorization);

const auto &fields = data.c_authorization();
auto result = Session();
result.platform = ParseString(fields.vplatform);
result.deviceModel = ParseString(fields.vdevice_model);
result.systemVersion = ParseString(fields.vsystem_version);
result.applicationName = ParseString(fields.vapp_name);
result.applicationVersion = ParseString(fields.vapp_version);
result.created = QDateTime::fromTime_t(fields.vdate_created.v);
result.lastActive = QDateTime::fromTime_t(fields.vdate_active.v);
result.ip = ParseString(fields.vip);
result.country = ParseString(fields.vcountry);
result.region = ParseString(fields.vregion);
return result;
}

SessionsList ParseSessionsList(const MTPaccount_Authorizations &data) {
Expects(data.type() == mtpc_account_authorizations);

auto result = SessionsList();
const auto &list = data.c_account_authorizations().vauthorizations.v;
for (const auto &session : list) {
result.list.push_back(ParseSession(session));
}
return result;
}

Utf8String FormatPhoneNumber(const Utf8String &phoneNumber) {
return phoneNumber.isEmpty()
? Utf8String()
Expand Down
18 changes: 17 additions & 1 deletion Telegram/SourceFiles/export/data/export_data_types.h
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,7 @@ struct ContactsList {
};

ContactsList ParseContactsList(const MTPcontacts_Contacts &data);
std::vector<int> SortedContactsIndices(const ContactsList &data);

struct Session {
Utf8String platform;
Expand All @@ -104,6 +105,8 @@ struct SessionsList {
std::vector<Session> list;
};

SessionsList ParseSessionsList(const MTPaccount_Authorizations &data);

struct ChatsInfo {
int count = 0;
};
Expand All @@ -127,11 +130,24 @@ struct MessagesSlice {
};

Utf8String FormatPhoneNumber(const Utf8String &phoneNumber);

Utf8String FormatDateTime(
const int32 date,
const QDateTime &date,
QChar dateSeparator = QChar('.'),
QChar timeSeparator = QChar(':'),
QChar separator = QChar(' '));

inline Utf8String FormatDateTime(
int32 date,
QChar dateSeparator = QChar('.'),
QChar timeSeparator = QChar(':'),
QChar separator = QChar(' ')) {
return FormatDateTime(
QDateTime::fromTime_t(date),
dateSeparator,
timeSeparator,
separator);
}

} // namespace Data
} // namespace Export
8 changes: 8 additions & 0 deletions Telegram/SourceFiles/export/export_api_wrap.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -243,6 +243,14 @@ void ApiWrap::requestContacts(FnMut<void(Data::ContactsList&&)> done) {
}).send();
}

void ApiWrap::requestSessions(FnMut<void(Data::SessionsList&&)> done) {
mainRequest(MTPaccount_GetAuthorizations(
)).done([=, done = std::move(done)](
const MTPaccount_Authorizations &result) mutable {
done(Data::ParseSessionsList(result));
}).send();
}

void ApiWrap::loadFile(const Data::File &file, FnMut<void(QString)> done) {
Expects(_fileProcess == nullptr);

Expand Down
3 changes: 3 additions & 0 deletions Telegram/SourceFiles/export/export_api_wrap.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ struct PersonalInfo;
struct UserpicsInfo;
struct UserpicsSlice;
struct ContactsList;
struct SessionsList;
} // namespace Data

class ApiWrap {
Expand All @@ -36,6 +37,8 @@ class ApiWrap {

void requestContacts(FnMut<void(Data::ContactsList&&)> done);

void requestSessions(FnMut<void(Data::SessionsList&&)> done);

~ApiWrap();

private:
Expand Down
5 changes: 4 additions & 1 deletion Telegram/SourceFiles/export/export_controller.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -261,7 +261,10 @@ void Controller::exportContacts() {
}

void Controller::exportSessions() {
exportNext();
_api.requestSessions([=](Data::SessionsList &&result) {
_writer->writeSessionsList(result);
exportNext();
});
}

void Controller::exportChats() {
Expand Down
48 changes: 29 additions & 19 deletions Telegram/SourceFiles/export/output/export_output_text.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -130,8 +130,7 @@ bool TextWriter::writeUserpicsSlice(const Data::UserpicsSlice &data) {
if (!userpic.date.isValid()) {
lines.append("(empty photo)");
} else {
lines.append(Data::FormatDateTime(userpic.date.toTime_t()));
lines.append(" - ");
lines.append(Data::FormatDateTime(userpic.date)).append(" - ");
if (userpic.image.relativePath.isEmpty()) {
lines.append("(file unavailable)");
} else {
Expand All @@ -154,28 +153,13 @@ bool TextWriter::writeContactsList(const Data::ContactsList &data) {
return true;
}

// Get sorted by name indices.
const auto names = ranges::view::all(
data.list
) | ranges::view::transform([](const Data::User &user) {
return (QString::fromUtf8(user.firstName)
+ ' '
+ QString::fromUtf8(user.lastName)).toLower();
}) | ranges::to_vector;

auto indices = ranges::view::ints(0, int(data.list.size()))
| ranges::to_vector;
ranges::sort(indices, [&](int i, int j) {
return names[i] < names[j];
});

const auto header = "Contacts "
"(" + Data::NumberToString(data.list.size()) + ")"
+ kLineBreak
+ kLineBreak;
auto list = std::vector<QByteArray>();
list.reserve(data.list.size());
for (const auto &index : indices) {
for (const auto &index : Data::SortedContactsIndices(data)) {
const auto &contact = data.list[index];
if (!contact.id) {
list.push_back("(user unavailable)");
Expand All @@ -199,7 +183,33 @@ bool TextWriter::writeContactsList(const Data::ContactsList &data) {
}

bool TextWriter::writeSessionsList(const Data::SessionsList &data) {
return true;
const auto header = "Sessions "
"(" + Data::NumberToString(data.list.size()) + ")"
+ kLineBreak
+ kLineBreak;
auto list = std::vector<QByteArray>();
list.reserve(data.list.size());
for (const auto &session : data.list) {
list.push_back(SerializeKeyValue({
{ "Last active", Data::FormatDateTime(session.lastActive) },
{ "Last IP address", session.ip },
{ "Last country", session.country },
{ "Last region", session.region },
{
"Application name",
(session.applicationName.isEmpty()
? Data::Utf8String("(unknown)")
: session.applicationName)
},
{ "Application version", session.applicationVersion },
{ "Device model", session.deviceModel },
{ "Platform", session.platform },
{ "System version", session.systemVersion },
{ "Created", Data::FormatDateTime(session.created) },
}));
}
const auto full = header + JoinList(kLineBreak, list) + kLineBreak;
return _result->writeBlock(full) == File::Result::Success;
}

bool TextWriter::writeChatsStart(const Data::ChatsInfo &data) {
Expand Down

0 comments on commit d3fdf43

Please sign in to comment.