summaryrefslogtreecommitdiff
path: root/libpurple
diff options
context:
space:
mode:
authorGary Kramlich <grim@reaperworld.com>2023-02-23 01:01:07 -0600
committerGary Kramlich <grim@reaperworld.com>2023-02-23 01:01:07 -0600
commit48c76aa1200cd3d864017c8906d43eb8612b12cb (patch)
tree686ca060d759b7c297d3e54b7d40547d73ef0a41 /libpurple
parent5ecd0c3d0bc426b78b2fa9a5e52cea00d23ee0a1 (diff)
downloadpidgin-48c76aa1200cd3d864017c8906d43eb8612b12cb.tar.gz
Add an error property to PurpleMessage
There are a number of ways that an individual message can fail, and it would be nice to let the user interface know that it failed, so that the user can attempt to resend. Testing Done: Ran the unit tests (that I just added) Bugs closed: PIDGIN-17757 Reviewed at https://reviews.imfreedom.org/r/2234/
Diffstat (limited to 'libpurple')
-rw-r--r--libpurple/purplemessage.c44
-rw-r--r--libpurple/purplemessage.h23
-rw-r--r--libpurple/tests/meson.build1
-rw-r--r--libpurple/tests/test_message.c108
4 files changed, 176 insertions, 0 deletions
diff --git a/libpurple/purplemessage.c b/libpurple/purplemessage.c
index fbd3a71af0..b45189bc91 100644
--- a/libpurple/purplemessage.c
+++ b/libpurple/purplemessage.c
@@ -42,6 +42,8 @@ struct _PurpleMessage {
GDateTime *timestamp;
PurpleMessageFlags flags;
+ GError *error;
+
GHashTable *attachments;
};
@@ -56,6 +58,7 @@ enum {
PROP_CONTENT_TYPE,
PROP_TIMESTAMP,
PROP_FLAGS,
+ PROP_ERROR,
N_PROPERTIES
};
static GParamSpec *properties[N_PROPERTIES];
@@ -119,6 +122,9 @@ purple_message_get_property(GObject *object, guint param_id, GValue *value,
case PROP_FLAGS:
g_value_set_flags(value, purple_message_get_flags(message));
break;
+ case PROP_ERROR:
+ g_value_set_boxed(value, purple_message_get_error(message));
+ break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID(object, param_id, pspec);
break;
@@ -160,6 +166,9 @@ purple_message_set_property(GObject *object, guint param_id,
case PROP_FLAGS:
purple_message_set_flags(message, g_value_get_flags(value));
break;
+ case PROP_ERROR:
+ purple_message_set_error(message, g_value_get_boxed(value));
+ break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID(object, param_id, pspec);
break;
@@ -177,6 +186,8 @@ purple_message_finalize(GObject *obj) {
g_free(message->recipient);
g_free(message->contents);
+ g_clear_error(&message->error);
+
if(message->timestamp != NULL) {
g_date_time_unref(message->timestamp);
}
@@ -317,6 +328,20 @@ purple_message_class_init(PurpleMessageClass *klass) {
PURPLE_TYPE_MESSAGE_FLAGS, 0,
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
+ /**
+ * PurpleMessage:error:
+ *
+ * An error that this message encountered. This could be something like a
+ * failed delivery, or failed redaction, or rate limited, etc.
+ *
+ * Since: 3.0.0
+ */
+ properties[PROP_ERROR] = g_param_spec_boxed(
+ "error", "error",
+ "An error that the message encountered",
+ G_TYPE_ERROR,
+ G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
+
g_object_class_install_properties(obj_class, N_PROPERTIES, properties);
}
@@ -574,6 +599,25 @@ purple_message_get_flags(PurpleMessage *message) {
return message->flags;
}
+void
+purple_message_set_error(PurpleMessage *message, GError *error) {
+ g_return_if_fail(PURPLE_IS_MESSAGE(message));
+
+ g_clear_error(&message->error);
+ if(error != NULL) {
+ g_propagate_error(&message->error, error);
+ }
+
+ g_object_notify_by_pspec(G_OBJECT(message), properties[PROP_ERROR]);
+}
+
+GError *
+purple_message_get_error(PurpleMessage *message) {
+ g_return_val_if_fail(PURPLE_IS_MESSAGE(message), NULL);
+
+ return message->error;
+}
+
gboolean
purple_message_add_attachment(PurpleMessage *message,
PurpleAttachment *attachment)
diff --git a/libpurple/purplemessage.h b/libpurple/purplemessage.h
index ef7b489523..dfcf242409 100644
--- a/libpurple/purplemessage.h
+++ b/libpurple/purplemessage.h
@@ -378,6 +378,29 @@ void purple_message_set_flags(PurpleMessage *message, PurpleMessageFlags flags);
PurpleMessageFlags purple_message_get_flags(PurpleMessage *message);
/**
+ * purple_message_set_error:
+ * @message: The instance.
+ * @error: (nullable) (transfer full): The error to set.
+ *
+ * Sets the error of @message to at @error.
+ *
+ * Since: 3.0.0
+ */
+void purple_message_set_error(PurpleMessage *message, GError *error);
+
+/**
+ * purple_message_get_error:
+ * @message: The instance.
+ *
+ * Gets the error from @message.
+ *
+ * Returns: (nullable) (transfer none): The error from @message or %NULL.
+ *
+ * Since: 3.0.0
+ */
+GError *purple_message_get_error(PurpleMessage *message);
+
+/**
* purple_message_add_attachment:
* @message: The #PurpleMessage instance.
* @attachment: The #PurpleAttachment instance.
diff --git a/libpurple/tests/meson.build b/libpurple/tests/meson.build
index a38b868872..697e818d59 100644
--- a/libpurple/tests/meson.build
+++ b/libpurple/tests/meson.build
@@ -14,6 +14,7 @@ PROGS = [
'keyvaluepair',
'markup',
'menu',
+ 'message',
'notification',
'notification_manager',
'person',
diff --git a/libpurple/tests/test_message.c b/libpurple/tests/test_message.c
new file mode 100644
index 0000000000..3ac15c4a4a
--- /dev/null
+++ b/libpurple/tests/test_message.c
@@ -0,0 +1,108 @@
+/*
+ * Purple - Internet Messaging Library
+ * Copyright (C) Pidgin Developers <devel@pidgin.im>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, see <https://www.gnu.org/licenses/>.
+ */
+
+#include <glib.h>
+
+#include <purple.h>
+
+/******************************************************************************
+ * Tests
+ *****************************************************************************/
+static void
+test_purple_message_properties(void) {
+ PurpleMessage *message = NULL;
+ PurpleMessageContentType content_type = 0;
+ PurpleMessageFlags flags = 0;
+ GDateTime *timestamp = NULL;
+ GDateTime *timestamp1 = NULL;
+ GError *error = NULL;
+ GError *error1 = NULL;
+ char *id = NULL;
+ char *author = NULL;
+ char *author_alias = NULL;
+ char *author_name_color = NULL;
+ char *recipient = NULL;
+ char *contents = NULL;
+
+ timestamp = g_date_time_new_from_unix_utc(911347200);
+ error = g_error_new(g_quark_from_static_string("test-message"), 0,
+ "delivery failed");
+
+ message = g_object_new(
+ PURPLE_TYPE_MESSAGE,
+ "id", "id",
+ "author", "author",
+ "author-alias", "alias",
+ "author-name-color", "purple",
+ "recipient", "pidgy",
+ "contents", "Now that is a big door",
+ "content-type", PURPLE_MESSAGE_CONTENT_TYPE_MARKDOWN,
+ "timestamp", timestamp,
+ "flags", PURPLE_MESSAGE_SYSTEM,
+ "error", error,
+ NULL);
+
+ g_object_get(
+ message,
+ "id", &id,
+ "author", &author,
+ "author-alias", &author_alias,
+ "author-name-color", &author_name_color,
+ "recipient", &recipient,
+ "contents", &contents,
+ "content-type", &content_type,
+ "timestamp", &timestamp1,
+ "flags", &flags,
+ "error", &error1,
+ NULL);
+
+ g_assert_cmpstr(id, ==, "id");
+ g_assert_cmpstr(author, ==, "author");
+ g_assert_cmpstr(author_alias, ==, "alias");
+ g_assert_cmpstr(author_name_color, ==, "purple");
+ g_assert_cmpstr(recipient, ==, "pidgy");
+ g_assert_cmpstr(contents, ==, "Now that is a big door");
+ g_assert_cmpint(content_type, ==, PURPLE_MESSAGE_CONTENT_TYPE_MARKDOWN);
+ g_assert_true(g_date_time_equal(timestamp1, timestamp));
+ g_assert_cmpint(flags, ==, PURPLE_MESSAGE_SYSTEM);
+ g_assert_error(error1, error->domain, error->code);
+
+ g_clear_pointer(&id, g_free);
+ g_clear_pointer(&author, g_free);
+ g_clear_pointer(&author_alias, g_free);
+ g_clear_pointer(&author_name_color, g_free);
+ g_clear_pointer(&recipient, g_free);
+ g_clear_pointer(&contents, g_free);
+ g_clear_pointer(&timestamp, g_date_time_unref);
+ g_clear_pointer(&timestamp1, g_date_time_unref);
+ g_clear_error(&error1);
+ g_clear_object(&message);
+}
+
+/******************************************************************************
+ * Main
+ *****************************************************************************/
+gint
+main(gint argc, gchar *argv[]) {
+ g_test_init(&argc, &argv, NULL);
+
+ g_test_add_func("/message/properties",
+ test_purple_message_properties);
+
+ return g_test_run();
+}