event-popover: Add support for Teams links

Add a separate function to extract the description and the URL from a
Teams-formatted event. Add a test for this as well.

Closes: https://gitlab.gnome.org/GNOME/gnome-calendar/-/work_items/1312
Part-of: <https://gitlab.gnome.org/GNOME/gnome-calendar/-/merge_requests/753>
This commit is contained in:
Jan-Michael Brummer
2026-05-26 19:55:25 -03:00
committed by Georges Basile Stavracas Neto
parent 823daa3fb1
commit ef5935f1fa
5 changed files with 152 additions and 14 deletions
+2 -3
View File
@@ -491,9 +491,8 @@ setup_description_label (GcalEventPopover *self)
g_autofree gchar *meeting_url = NULL;
g_autoptr (GString) string = NULL;
gcal_utils_extract_google_section (gcal_event_get_description (self->event),
&description,
&meeting_url);
gcal_utils_extract_meeting_url (gcal_event_get_description (self->event), &description, &meeting_url);
g_strstrip (description);
if (meeting_url)
+1 -3
View File
@@ -170,9 +170,7 @@ fill_grid_with_event_data (GcalImportFileRow *self,
}
}
gcal_utils_extract_google_section (i_cal_component_get_description (ical_component),
&description,
NULL);
gcal_utils_extract_meeting_url (i_cal_component_get_description (ical_component), &description, NULL);
add_grid_row (self, grid, row++, _("Title"), i_cal_component_get_summary (ical_component));
add_grid_row (self, grid, row++, _("Location"), i_cal_component_get_location (ical_component));
+87 -5
View File
@@ -1104,7 +1104,7 @@ gcal_utils_format_filename_for_display (const gchar *filename)
return g_steal_pointer (&display_name);
}
void
static gboolean
gcal_utils_extract_google_section (const gchar *description,
gchar **out_description,
gchar **out_meeting_url)
@@ -1117,21 +1117,21 @@ gcal_utils_extract_google_section (const gchar *description,
gchar *last_delimiter;
if (!description)
goto out;
return FALSE;
#define GOOGLE_DELIMITER "-::~:~::~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~::~:~::-"
description_len = strlen (description);
first_delimiter = g_strstr_len (description, description_len, GOOGLE_DELIMITER);
if (!first_delimiter)
goto out;
return FALSE;
delimiter_len = strlen (GOOGLE_DELIMITER);
last_delimiter = g_strstr_len (first_delimiter + delimiter_len,
description_len,
GOOGLE_DELIMITER);
if (!last_delimiter)
goto out;
return FALSE;
if (out_description)
actual_description = g_utf8_substring (description, 0, first_delimiter - description);
@@ -1149,12 +1149,94 @@ gcal_utils_extract_google_section (const gchar *description,
meeting_url = g_utf8_substring (meet_url_start, 0, strlen ("https://meet.google.com/xxx-xxxx-xxx"));
}
out:
if (out_description)
*out_description = actual_description ? g_steal_pointer (&actual_description) : g_strdup (description);
if (out_meeting_url)
*out_meeting_url = g_steal_pointer (&meeting_url);
return TRUE;
}
static gboolean
gcal_utils_extract_teams_section (const gchar *description,
gchar **out_description,
gchar **out_meeting_url)
{
g_autofree gchar *actual_description = NULL;
g_autofree gchar *meeting_url = NULL;
gssize description_len;
gsize delimiter_len;
gchar *first_delimiter;
gchar *last_delimiter;
if (!description)
return FALSE;
#define TEAMS_DELIMITER "________________________________________________________________________________"
description_len = strlen (description);
first_delimiter = g_strstr_len (description, description_len, TEAMS_DELIMITER);
if (!first_delimiter)
return FALSE;
delimiter_len = strlen (TEAMS_DELIMITER);
last_delimiter = g_strstr_len (first_delimiter + delimiter_len,
description_len,
TEAMS_DELIMITER);
if (!last_delimiter)
return FALSE;
if (out_description)
actual_description = g_utf8_substring (description, 0, first_delimiter - description);
if (out_meeting_url)
{
gchar *teams_section_start;
gchar *meet_url_start;
teams_section_start = first_delimiter + delimiter_len;
meet_url_start = g_strstr_len (teams_section_start,
last_delimiter - first_delimiter,
"https://teams.microsoft.com");
if (meet_url_start)
{
char *end = g_strstr_len (meet_url_start + 1, -1, "\n");
meeting_url = g_utf8_substring (meet_url_start, 0, end - meet_url_start);
}
}
if (out_description)
*out_description = actual_description ? g_steal_pointer (&actual_description) : g_strdup (description);
if (out_meeting_url)
*out_meeting_url = g_steal_pointer (&meeting_url);
return TRUE;
}
/**
* gcal_utils_extract_meeting_url:
* @description: (nullable): a string description
* @out_description: (nullable)(transfer full): return location for a parsed description
* @out_meeting_url: (nullable)(transfer full): return location for the parsed meeting url
*
* Parses @description for meeting URLs.
*/
void
gcal_utils_extract_meeting_url (const char *description,
char **out_description,
char **out_meeting_url)
{
if (!gcal_utils_extract_google_section (description, out_description, out_meeting_url) &&
!gcal_utils_extract_teams_section (description, out_description, out_meeting_url))
{
if (out_description)
*out_description = g_strdup (description);
if (out_meeting_url)
*out_meeting_url = NULL;
}
}
typedef struct
+3 -3
View File
@@ -118,9 +118,9 @@ void gcal_utils_launch_gnome_settings (GDBusConnectio
gchar* gcal_utils_format_filename_for_display (const gchar *filename);
void gcal_utils_extract_google_section (const gchar *description,
gchar **out_description,
gchar **out_meeting_url);
void gcal_utils_extract_meeting_url (const char *description,
char **out_description,
char **out_meeting_url);
void gcal_utils_ask_recurrence_modification_type (GtkWidget *parent,
GcalEvent *event,
+59
View File
@@ -133,6 +133,64 @@ date_time_from_icaltime (void)
/*********************************************************************************************************************/
#define GOOGLE_SAMPLE_DESCRIPTION \
"-::~:~::~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~::~:~::-\n" \
"Entrar com o Google Meet: https://meet.google.com/abc-defg-hij\n" \
"\n" \
"Saiba mais sobre o Meet em: https://support.google.com/a/users/answer/9282720\n" \
"\n" \
"Não edite esta seção.\n" \
"-::~:~::~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~::~:~::-"
#define GOOGLE_SAMPLE_DESCRIPTION_WITH_COMMENT \
"TROLOLO\n" \
"-::~:~::~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~::~:~::-\n" \
"Entrar com o Google Meet: https://meet.google.com/abc-defg-hij\n" \
"\n" \
"Saiba mais sobre o Meet em: https://support.google.com/a/users/answer/9282720\n" \
"\n" \
"Não edite esta seção.\n" \
"-::~:~::~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~::~:~::-"
#define TEAMS_SAMPLE_DESCRIPTION \
"________________________________________________________________________________\n" \
"Réunion Microsoft Teams\n" \
"Joindre : https://teams.microsoft.com/meet/12345678912345?p=0AbCdEfGjKLm1nOjTj\n" \
"Numéro de réunion : 123 456 789 123 45\n" \
"Code secret : abcdefgh\n" \
"________________________________\n" \
"Besoin d’aide?<https://aka.ms/JoinTeamsMeeting?omkt=fr-CA> | Référence système<https://teams.microsoft.com/l/meetup-join/19%3ameeting_KLMNTABC02UJKL5OC00ZWJhLThhNDgtYmJlYTI2ZTE5YzM0%40abc.v2/0?context=%7b%22Tid%22%3a%3f5f042f-920a-4035-8dc7-477b5dce3c73%22%2c%22Oid%22%3a%aa4dd47c-47a1-4a00-b766-6e5f83e7d367%22%7d>\n" \
"Pour les organisateurs : Options de réunion<https://teams.microsoft.com/meetingOptions/?organizerId=690add55-d0e3-4605-ac28-a3a08193c212&tenantId=43743467-968a-4ded-8250-afd003a4a407&threadId=19_meeting_Yjk5NTI0M2UtNjA5OC00ZWJhLThhNDgtYmJlYTI2ZTE5YzM0&messageId=100&language=fr-CA>\n" \
"________________________________________________________________________________"
static void
extract_meeting_url (void)
{
g_autofree char *description = NULL;
g_autofree char *meeting_url = NULL;
gcal_utils_extract_meeting_url (GOOGLE_SAMPLE_DESCRIPTION, &description, &meeting_url);
g_assert_cmpstr (description, ==, "");
g_assert_cmpstr (meeting_url, ==, "https://meet.google.com/abc-defg-hij");
g_clear_pointer (&description, g_free);
g_clear_pointer (&meeting_url, g_free);
gcal_utils_extract_meeting_url (GOOGLE_SAMPLE_DESCRIPTION_WITH_COMMENT, &description, &meeting_url);
g_assert_cmpstr (description, ==, "TROLOLO\n");
g_assert_cmpstr (meeting_url, ==, "https://meet.google.com/abc-defg-hij");
g_clear_pointer (&description, g_free);
g_clear_pointer (&meeting_url, g_free);
gcal_utils_extract_meeting_url (TEAMS_SAMPLE_DESCRIPTION, &description, &meeting_url);
g_assert_cmpstr (description, ==, "");
g_assert_cmpstr (meeting_url, ==, "https://teams.microsoft.com/meet/12345678912345?p=0AbCdEfGjKLm1nOjTj");
}
/*********************************************************************************************************************/
gint
main (gint argc,
gchar *argv[])
@@ -143,6 +201,7 @@ main (gint argc,
g_test_bug_base ("https://gitlab.gnome.org/GNOME/gnome-calendar/-/issues/");
g_test_add_func ("/utils/date-time/date_time_from_icaltime", date_time_from_icaltime);
g_test_add_func ("/utils/misc/extract_meeting_url", extract_meeting_url);
return g_test_run ();
}