mirror of https://github.com/procxx/kepka.git
Add saving of shared contacts vcards in export.
This commit is contained in:
parent
a43dfc567c
commit
5cdc563c9e
|
@ -364,6 +364,26 @@ Document ParseDocument(
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SharedContact ParseSharedContact(
|
||||||
|
ParseMediaContext &context,
|
||||||
|
const MTPDmessageMediaContact &data,
|
||||||
|
const QString &suggestedFolder) {
|
||||||
|
auto result = SharedContact();
|
||||||
|
result.info.userId = data.vuser_id.v;
|
||||||
|
result.info.firstName = ParseString(data.vfirst_name);
|
||||||
|
result.info.lastName = ParseString(data.vlast_name);
|
||||||
|
result.info.phoneNumber = ParseString(data.vphone_number);
|
||||||
|
if (!data.vvcard.v.isEmpty()) {
|
||||||
|
result.vcard.content = data.vvcard.v;
|
||||||
|
result.vcard.size = data.vvcard.v.size();
|
||||||
|
result.vcard.suggestedPath = suggestedFolder
|
||||||
|
+ "contacts/contact_"
|
||||||
|
+ QString::number(++context.contacts)
|
||||||
|
+ ".vcard";
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
GeoPoint ParseGeoPoint(const MTPGeoPoint &data) {
|
GeoPoint ParseGeoPoint(const MTPGeoPoint &data) {
|
||||||
auto result = GeoPoint();
|
auto result = GeoPoint();
|
||||||
data.match([&](const MTPDgeoPoint &data) {
|
data.match([&](const MTPDgeoPoint &data) {
|
||||||
|
@ -439,15 +459,6 @@ ContactInfo ParseContactInfo(const MTPUser &data) {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
ContactInfo ParseContactInfo(const MTPDmessageMediaContact &data) {
|
|
||||||
auto result = ContactInfo();
|
|
||||||
result.userId = data.vuser_id.v;
|
|
||||||
result.firstName = ParseString(data.vfirst_name);
|
|
||||||
result.lastName = ParseString(data.vlast_name);
|
|
||||||
result.phoneNumber = ParseString(data.vphone_number);
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
User ParseUser(const MTPUser &data) {
|
User ParseUser(const MTPUser &data) {
|
||||||
auto result = User();
|
auto result = User();
|
||||||
result.info = ParseContactInfo(data);
|
result.info = ParseContactInfo(data);
|
||||||
|
@ -617,6 +628,8 @@ File &Media::file() {
|
||||||
return data.image.file;
|
return data.image.file;
|
||||||
}, [](Document &data) -> File& {
|
}, [](Document &data) -> File& {
|
||||||
return data.file;
|
return data.file;
|
||||||
|
}, [](SharedContact &data) -> File& {
|
||||||
|
return data.vcard;
|
||||||
}, [](auto&) -> File& {
|
}, [](auto&) -> File& {
|
||||||
static File result;
|
static File result;
|
||||||
return result;
|
return result;
|
||||||
|
@ -628,6 +641,8 @@ const File &Media::file() const {
|
||||||
return data.image.file;
|
return data.image.file;
|
||||||
}, [](const Document &data) -> const File& {
|
}, [](const Document &data) -> const File& {
|
||||||
return data.file;
|
return data.file;
|
||||||
|
}, [](const SharedContact &data) -> const File& {
|
||||||
|
return data.vcard;
|
||||||
}, [](const auto &) -> const File& {
|
}, [](const auto &) -> const File& {
|
||||||
static const File result;
|
static const File result;
|
||||||
return result;
|
return result;
|
||||||
|
@ -654,7 +669,7 @@ Media ParseMedia(
|
||||||
}, [&](const MTPDmessageMediaGeo &data) {
|
}, [&](const MTPDmessageMediaGeo &data) {
|
||||||
result.content = ParseGeoPoint(data.vgeo);
|
result.content = ParseGeoPoint(data.vgeo);
|
||||||
}, [&](const MTPDmessageMediaContact &data) {
|
}, [&](const MTPDmessageMediaContact &data) {
|
||||||
result.content = ParseContactInfo(data);
|
result.content = ParseSharedContact(context, data, folder);
|
||||||
}, [&](const MTPDmessageMediaUnsupported &data) {
|
}, [&](const MTPDmessageMediaUnsupported &data) {
|
||||||
result.content = UnsupportedMedia();
|
result.content = UnsupportedMedia();
|
||||||
}, [&](const MTPDmessageMediaDocument &data) {
|
}, [&](const MTPDmessageMediaDocument &data) {
|
||||||
|
|
|
@ -77,6 +77,18 @@ struct Image {
|
||||||
File file;
|
File file;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct ContactInfo {
|
||||||
|
int32 userId = 0;
|
||||||
|
Utf8String firstName;
|
||||||
|
Utf8String lastName;
|
||||||
|
Utf8String phoneNumber;
|
||||||
|
TimeId date = 0;
|
||||||
|
|
||||||
|
Utf8String name() const;
|
||||||
|
};
|
||||||
|
|
||||||
|
ContactInfo ParseContactInfo(const MTPUser &data);
|
||||||
|
|
||||||
struct Photo {
|
struct Photo {
|
||||||
uint64 id = 0;
|
uint64 id = 0;
|
||||||
TimeId date = 0;
|
TimeId date = 0;
|
||||||
|
@ -108,6 +120,11 @@ struct Document {
|
||||||
bool isAudioFile = false;
|
bool isAudioFile = false;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct SharedContact {
|
||||||
|
ContactInfo info;
|
||||||
|
File vcard;
|
||||||
|
};
|
||||||
|
|
||||||
struct GeoPoint {
|
struct GeoPoint {
|
||||||
float64 latitude = 0.;
|
float64 latitude = 0.;
|
||||||
float64 longitude = 0.;
|
float64 longitude = 0.;
|
||||||
|
@ -145,19 +162,6 @@ UserpicsSlice ParseUserpicsSlice(
|
||||||
const MTPVector<MTPPhoto> &data,
|
const MTPVector<MTPPhoto> &data,
|
||||||
int baseIndex);
|
int baseIndex);
|
||||||
|
|
||||||
struct ContactInfo {
|
|
||||||
int32 userId = 0;
|
|
||||||
Utf8String firstName;
|
|
||||||
Utf8String lastName;
|
|
||||||
Utf8String phoneNumber;
|
|
||||||
TimeId date = 0;
|
|
||||||
|
|
||||||
Utf8String name() const;
|
|
||||||
};
|
|
||||||
|
|
||||||
ContactInfo ParseContactInfo(const MTPUser &data);
|
|
||||||
ContactInfo ParseContactInfo(const MTPDmessageMediaContact &data);
|
|
||||||
|
|
||||||
struct User {
|
struct User {
|
||||||
ContactInfo info;
|
ContactInfo info;
|
||||||
Utf8String username;
|
Utf8String username;
|
||||||
|
@ -264,7 +268,7 @@ struct Media {
|
||||||
base::optional_variant<
|
base::optional_variant<
|
||||||
Photo,
|
Photo,
|
||||||
Document,
|
Document,
|
||||||
ContactInfo,
|
SharedContact,
|
||||||
GeoPoint,
|
GeoPoint,
|
||||||
Venue,
|
Venue,
|
||||||
Game,
|
Game,
|
||||||
|
@ -281,6 +285,7 @@ struct ParseMediaContext {
|
||||||
int audios = 0;
|
int audios = 0;
|
||||||
int videos = 0;
|
int videos = 0;
|
||||||
int files = 0;
|
int files = 0;
|
||||||
|
int contacts = 0;
|
||||||
int32 botId = 0;
|
int32 botId = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -297,6 +297,9 @@ ApiWrap::LoadedFileCache::LoadedFileCache(int limit) : _limit(limit) {
|
||||||
void ApiWrap::LoadedFileCache::save(
|
void ApiWrap::LoadedFileCache::save(
|
||||||
const Location &location,
|
const Location &location,
|
||||||
const QString &relativePath) {
|
const QString &relativePath) {
|
||||||
|
if (!location) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
const auto key = ComputeLocationKey(location);
|
const auto key = ComputeLocationKey(location);
|
||||||
_map[key] = relativePath;
|
_map[key] = relativePath;
|
||||||
_list.push_back(key);
|
_list.push_back(key);
|
||||||
|
@ -309,6 +312,9 @@ void ApiWrap::LoadedFileCache::save(
|
||||||
|
|
||||||
base::optional<QString> ApiWrap::LoadedFileCache::find(
|
base::optional<QString> ApiWrap::LoadedFileCache::find(
|
||||||
const Location &location) const {
|
const Location &location) const {
|
||||||
|
if (!location) {
|
||||||
|
return base::none;
|
||||||
|
}
|
||||||
const auto key = ComputeLocationKey(location);
|
const auto key = ComputeLocationKey(location);
|
||||||
if (const auto i = _map.find(key); i != end(_map)) {
|
if (const auto i = _map.find(key); i != end(_map)) {
|
||||||
return i->second;
|
return i->second;
|
||||||
|
@ -1307,7 +1313,7 @@ bool ApiWrap::processFileLoad(
|
||||||
|
|
||||||
if (!file.relativePath.isEmpty()) {
|
if (!file.relativePath.isEmpty()) {
|
||||||
return true;
|
return true;
|
||||||
} else if (!file.location) {
|
} else if (!file.location && file.content.isEmpty()) {
|
||||||
file.skipReason = SkipReason::Unavailable;
|
file.skipReason = SkipReason::Unavailable;
|
||||||
return true;
|
return true;
|
||||||
} else if (writePreloadedFile(file)) {
|
} else if (writePreloadedFile(file)) {
|
||||||
|
@ -1355,8 +1361,7 @@ bool ApiWrap::writePreloadedFile(Data::File &file) {
|
||||||
return true;
|
return true;
|
||||||
} else if (!file.content.isEmpty()) {
|
} else if (!file.content.isEmpty()) {
|
||||||
const auto process = prepareFileProcess(file);
|
const auto process = prepareFileProcess(file);
|
||||||
auto &output = _fileProcess->file;
|
if (const auto result = process->file.writeBlock(file.content)) {
|
||||||
if (const auto result = output.writeBlock(file.content)) {
|
|
||||||
file.relativePath = process->relativePath;
|
file.relativePath = process->relativePath;
|
||||||
_fileCache->save(file.location, file.relativePath);
|
_fileCache->save(file.location, file.relativePath);
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -239,7 +239,9 @@ Stats AbstractWriter::produceTestExample(const QString &path) {
|
||||||
}());
|
}());
|
||||||
sliceBot1.list.push_back([&] {
|
sliceBot1.list.push_back([&] {
|
||||||
auto message = sampleMessage();
|
auto message = sampleMessage();
|
||||||
message.media.content = user.info;
|
auto contact = Data::SharedContact();
|
||||||
|
contact.info = user.info;
|
||||||
|
message.media.content = contact;
|
||||||
return message;
|
return message;
|
||||||
}());
|
}());
|
||||||
auto sliceBot2 = Data::MessagesSlice();
|
auto sliceBot2 = Data::MessagesSlice();
|
||||||
|
|
|
@ -482,12 +482,15 @@ QByteArray SerializeMessage(
|
||||||
push("Height", NumberToString(data.height));
|
push("Height", NumberToString(data.height));
|
||||||
}
|
}
|
||||||
pushTTL();
|
pushTTL();
|
||||||
}, [&](const ContactInfo &data) {
|
}, [&](const SharedContact &data) {
|
||||||
pushBare("Contact information", SerializeKeyValue({
|
pushBare("Contact information", SerializeKeyValue({
|
||||||
{ "First name", data.firstName },
|
{ "First name", data.info.firstName },
|
||||||
{ "Last name", data.lastName },
|
{ "Last name", data.info.lastName },
|
||||||
{ "Phone number", FormatPhoneNumber(data.phoneNumber) },
|
{ "Phone number", FormatPhoneNumber(data.info.phoneNumber) },
|
||||||
}));
|
}));
|
||||||
|
if (!data.vcard.content.isEmpty()) {
|
||||||
|
pushPath(data.vcard, "Contact vcard");
|
||||||
|
}
|
||||||
}, [&](const GeoPoint &data) {
|
}, [&](const GeoPoint &data) {
|
||||||
pushBare("Location", data.valid ? SerializeKeyValue({
|
pushBare("Location", data.valid ? SerializeKeyValue({
|
||||||
{ "Latitude", NumberToString(data.latitude) },
|
{ "Latitude", NumberToString(data.latitude) },
|
||||||
|
|
|
@ -513,15 +513,18 @@ QByteArray SerializeMessage(
|
||||||
push("height", data.height);
|
push("height", data.height);
|
||||||
}
|
}
|
||||||
pushTTL();
|
pushTTL();
|
||||||
}, [&](const ContactInfo &data) {
|
}, [&](const SharedContact &data) {
|
||||||
pushBare("contact_information", SerializeObject(context, {
|
pushBare("contact_information", SerializeObject(context, {
|
||||||
{ "first_name", SerializeString(data.firstName) },
|
{ "first_name", SerializeString(data.info.firstName) },
|
||||||
{ "last_name", SerializeString(data.lastName) },
|
{ "last_name", SerializeString(data.info.lastName) },
|
||||||
{
|
{
|
||||||
"phone_number",
|
"phone_number",
|
||||||
SerializeString(FormatPhoneNumber(data.phoneNumber))
|
SerializeString(FormatPhoneNumber(data.info.phoneNumber))
|
||||||
},
|
}
|
||||||
}));
|
}));
|
||||||
|
if (!data.vcard.content.isEmpty()) {
|
||||||
|
pushPath(data.vcard, "contact_vcard");
|
||||||
|
}
|
||||||
}, [&](const GeoPoint &data) {
|
}, [&](const GeoPoint &data) {
|
||||||
pushBare(
|
pushBare(
|
||||||
"location_information",
|
"location_information",
|
||||||
|
|
|
@ -382,12 +382,15 @@ QByteArray SerializeMessage(
|
||||||
push("Height", NumberToString(data.height));
|
push("Height", NumberToString(data.height));
|
||||||
}
|
}
|
||||||
pushTTL();
|
pushTTL();
|
||||||
}, [&](const ContactInfo &data) {
|
}, [&](const SharedContact &data) {
|
||||||
push("Contact information", SerializeKeyValue({
|
push("Contact information", SerializeKeyValue({
|
||||||
{ "First name", data.firstName },
|
{ "First name", data.info.firstName },
|
||||||
{ "Last name", data.lastName },
|
{ "Last name", data.info.lastName },
|
||||||
{ "Phone number", FormatPhoneNumber(data.phoneNumber) },
|
{ "Phone number", FormatPhoneNumber(data.info.phoneNumber) },
|
||||||
}));
|
}));
|
||||||
|
if (!data.vcard.content.isEmpty()) {
|
||||||
|
pushPath(data.vcard, "Contact vcard");
|
||||||
|
}
|
||||||
}, [&](const GeoPoint &data) {
|
}, [&](const GeoPoint &data) {
|
||||||
push("Location", data.valid ? SerializeKeyValue({
|
push("Location", data.valid ? SerializeKeyValue({
|
||||||
{ "Latitude", NumberToString(data.latitude) },
|
{ "Latitude", NumberToString(data.latitude) },
|
||||||
|
|
Loading…
Reference in New Issue