Refactor ICS export
This commit is contained in:
parent
ed9fe9c563
commit
909bc98622
1 changed files with 81 additions and 144 deletions
|
|
@ -660,7 +660,7 @@ bool ConferenceInfoCore::isAllDayConf() const {
|
||||||
}
|
}
|
||||||
|
|
||||||
void ConferenceInfoCore::exportConferenceToICS() {
|
void ConferenceInfoCore::exportConferenceToICS() {
|
||||||
// Collect participant addresses to look up display names
|
// Collect participant addresses
|
||||||
QStringList participantAddresses;
|
QStringList participantAddresses;
|
||||||
for (const auto &participant : mParticipants) {
|
for (const auto &participant : mParticipants) {
|
||||||
auto map = participant.toMap();
|
auto map = participant.toMap();
|
||||||
|
|
@ -679,78 +679,9 @@ void ConferenceInfoCore::exportConferenceToICS() {
|
||||||
QDateTime dateTime = mDateTime;
|
QDateTime dateTime = mDateTime;
|
||||||
QDateTime endDateTime = mEndDateTime;
|
QDateTime endDateTime = mEndDateTime;
|
||||||
|
|
||||||
// Look up display names from friend list in model thread
|
// Generate ICS on model thread (for display name lookup) then open file
|
||||||
App::postModelAsync(
|
App::postModelAsync(
|
||||||
[participantAddresses, uri, organizerAddress, organizerName, subject, description, dateTime, endDateTime]() {
|
[participantAddresses, uri, organizerAddress, organizerName, subject, description, dateTime, endDateTime]() {
|
||||||
// Helper to extract phone number from SIP address
|
|
||||||
auto extractPhoneNumber = [](const QString &address) -> QString {
|
|
||||||
QString addr = address;
|
|
||||||
if (addr.startsWith("sip:", Qt::CaseInsensitive)) {
|
|
||||||
addr = addr.mid(4);
|
|
||||||
} else if (addr.startsWith("sips:", Qt::CaseInsensitive)) {
|
|
||||||
addr = addr.mid(5);
|
|
||||||
}
|
|
||||||
int atIndex = addr.indexOf('@');
|
|
||||||
if (atIndex > 0) {
|
|
||||||
return addr.left(atIndex);
|
|
||||||
}
|
|
||||||
return addr;
|
|
||||||
};
|
|
||||||
|
|
||||||
// Build map of address -> display name
|
|
||||||
QMap<QString, QString> displayNames;
|
|
||||||
auto appFriendList = ToolModel::getAppFriendList();
|
|
||||||
|
|
||||||
for (const QString &address : participantAddresses) {
|
|
||||||
QString displayName;
|
|
||||||
|
|
||||||
// First try standard lookup by address
|
|
||||||
auto linFriend = ToolModel::findFriendByAddress(address);
|
|
||||||
if (linFriend) {
|
|
||||||
displayName = Utils::coreStringToAppString(linFriend->getName());
|
|
||||||
}
|
|
||||||
|
|
||||||
// If not found, search by phone number in friend list
|
|
||||||
if (displayName.isEmpty() && appFriendList) {
|
|
||||||
QString phoneNumber = extractPhoneNumber(address);
|
|
||||||
if (!phoneNumber.isEmpty()) {
|
|
||||||
// Iterate through all friends and check their phone numbers
|
|
||||||
for (const auto &friendEntry : appFriendList->getFriends()) {
|
|
||||||
auto friendPhoneNumbers = friendEntry->getPhoneNumbers();
|
|
||||||
for (const auto &friendPhone : friendPhoneNumbers) {
|
|
||||||
QString friendPhoneStr = Utils::coreStringToAppString(friendPhone);
|
|
||||||
// Normalize both numbers for comparison (digits only)
|
|
||||||
QString normalizedFriendPhone = friendPhoneStr;
|
|
||||||
QString normalizedSearchPhone = phoneNumber;
|
|
||||||
normalizedFriendPhone.remove(QRegularExpression("[^0-9]"));
|
|
||||||
normalizedSearchPhone.remove(QRegularExpression("[^0-9]"));
|
|
||||||
// Check if phone numbers match
|
|
||||||
if (friendPhoneStr == phoneNumber || normalizedFriendPhone == normalizedSearchPhone) {
|
|
||||||
displayName = Utils::coreStringToAppString(friendEntry->getName());
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (!displayName.isEmpty()) break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Fallback to phone number if no display name found
|
|
||||||
if (displayName.isEmpty()) {
|
|
||||||
displayName = extractPhoneNumber(address);
|
|
||||||
}
|
|
||||||
|
|
||||||
displayNames[address] = displayName;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Write ICS file in main thread
|
|
||||||
App::postCoreAsync([participantAddresses, displayNames, uri, organizerAddress, organizerName, subject,
|
|
||||||
description, dateTime, endDateTime]() {
|
|
||||||
QString filePath(Paths::getAppLocalDirPath() + "conference.ics");
|
|
||||||
QFile file(filePath);
|
|
||||||
if (file.open(QIODevice::WriteOnly | QIODevice::Text)) {
|
|
||||||
QTextStream out(&file);
|
|
||||||
|
|
||||||
// Helper lambda to escape special characters in ICS text fields
|
// Helper lambda to escape special characters in ICS text fields
|
||||||
auto escapeIcsText = [](const QString &text) {
|
auto escapeIcsText = [](const QString &text) {
|
||||||
QString escaped = text;
|
QString escaped = text;
|
||||||
|
|
@ -762,9 +693,7 @@ void ConferenceInfoCore::exportConferenceToICS() {
|
||||||
};
|
};
|
||||||
|
|
||||||
// Helper lambda to format datetime in ICS format (UTC)
|
// Helper lambda to format datetime in ICS format (UTC)
|
||||||
auto formatIcsDateTime = [](const QDateTime &dt) {
|
auto formatIcsDateTime = [](const QDateTime &dt) { return dt.toUTC().toString("yyyyMMdd'T'HHmmss'Z'"); };
|
||||||
return dt.toUTC().toString("yyyyMMdd'T'HHmmss'Z'");
|
|
||||||
};
|
|
||||||
|
|
||||||
// Generate a unique UID based on URI or datetime + organizer
|
// Generate a unique UID based on URI or datetime + organizer
|
||||||
QString uid;
|
QString uid;
|
||||||
|
|
@ -777,6 +706,9 @@ void ConferenceInfoCore::exportConferenceToICS() {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Build the ICS content
|
// Build the ICS content
|
||||||
|
QString icsContent;
|
||||||
|
QTextStream out(&icsContent);
|
||||||
|
|
||||||
out << "BEGIN:VCALENDAR\r\n";
|
out << "BEGIN:VCALENDAR\r\n";
|
||||||
out << "VERSION:2.0\r\n";
|
out << "VERSION:2.0\r\n";
|
||||||
out << "PRODID:-//Titanium Comms//EN\r\n";
|
out << "PRODID:-//Titanium Comms//EN\r\n";
|
||||||
|
|
@ -800,7 +732,7 @@ void ConferenceInfoCore::exportConferenceToICS() {
|
||||||
|
|
||||||
// Attendees/Participants
|
// Attendees/Participants
|
||||||
for (const QString &address : participantAddresses) {
|
for (const QString &address : participantAddresses) {
|
||||||
QString displayName = displayNames.value(address);
|
QString displayName = ToolModel::getDisplayName(address);
|
||||||
out << "ATTENDEE;ROLE=REQ-PARTICIPANT;PARTSTAT=NEEDS-ACTION;RSVP=TRUE";
|
out << "ATTENDEE;ROLE=REQ-PARTICIPANT;PARTSTAT=NEEDS-ACTION;RSVP=TRUE";
|
||||||
if (!displayName.isEmpty()) {
|
if (!displayName.isEmpty()) {
|
||||||
out << ";CN=" << escapeIcsText(displayName);
|
out << ";CN=" << escapeIcsText(displayName);
|
||||||
|
|
@ -829,9 +761,14 @@ void ConferenceInfoCore::exportConferenceToICS() {
|
||||||
out << "END:VEVENT\r\n";
|
out << "END:VEVENT\r\n";
|
||||||
out << "END:VCALENDAR\r\n";
|
out << "END:VCALENDAR\r\n";
|
||||||
|
|
||||||
|
// Write the file and open it
|
||||||
|
QString filePath(Paths::getAppLocalDirPath() + "conference.ics");
|
||||||
|
QFile file(filePath);
|
||||||
|
if (file.open(QIODevice::WriteOnly | QIODevice::Text)) {
|
||||||
|
QTextStream fileOut(&file);
|
||||||
|
fileOut << icsContent;
|
||||||
file.close();
|
file.close();
|
||||||
}
|
}
|
||||||
QDesktopServices::openUrl(QUrl::fromLocalFile(filePath));
|
QDesktopServices::openUrl(QUrl::fromLocalFile(filePath));
|
||||||
});
|
});
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue