protocols/demo/purpledemocontacts.c

changeset 42652
225762d4e206
parent 42312
7d6f0b8b6e77
child 42747
801025bad2e1
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/protocols/demo/purpledemocontacts.c	Mon Mar 25 21:43:28 2024 -0500
@@ -0,0 +1,357 @@
+/*
+ * 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 <json-glib/json-glib.h>
+
+#include "purpledemocontacts.h"
+
+#include "purpledemoresource.h"
+
+/******************************************************************************
+ * Helpers
+ *****************************************************************************/
+static void
+purple_demo_contacts_load_contact_icon(PurpleContactInfo *info,
+                                       const char *name)
+{
+	PurpleAvatar *avatar = NULL;
+	GError *error = NULL;
+	char *path = NULL;
+
+	path = g_strdup_printf("/im/pidgin/purple/demo/buddy_icons/%s.png", name);
+	avatar = purple_avatar_new_from_resource(path, &error);
+
+	if(error != NULL) {
+		g_message("Failed to load find an icon for %s: %s", path,
+		          error->message);
+
+		g_free(path);
+		g_clear_error(&error);
+
+		return;
+	}
+
+	g_free(path);
+
+	if(PURPLE_IS_AVATAR(avatar)) {
+		purple_contact_info_set_avatar(info, avatar);
+
+		g_clear_object(&avatar);
+	}
+}
+
+static void
+purple_demo_contacts_load_contact_person(JsonObject *person_object,
+                                         PurpleContactInfo *info)
+{
+	PurplePerson *person = NULL;
+	gboolean new_person = FALSE;
+	const char *value = NULL;
+
+	/* If the person has an id, grab it so we can use it when constructing the
+	 * person object.
+	 */
+	if(json_object_has_member(person_object, "id")) {
+		value = json_object_get_string_member(person_object, "id");
+	}
+
+	/* See if the contact has an existing person. */
+	person = purple_contact_info_get_person(info);
+	if(PURPLE_IS_PERSON(person)) {
+		const char *existing_id = NULL;
+
+		/* If the existing person's id doesn't match the new one, NULL out
+		 * person so it'll be recreated with the new id.
+		 */
+		existing_id = purple_person_get_id(person);
+		if(!purple_strequal(existing_id, value)) {
+			person = NULL;
+		}
+	}
+
+	/* If the person didn't exist or it had a different id, create a new person
+	 * with the id.
+	 */
+	if(!PURPLE_IS_PERSON(person)) {
+		person = g_object_new(PURPLE_TYPE_PERSON, "id", value, NULL);
+		new_person = TRUE;
+	}
+
+	/* Alias */
+	if(json_object_has_member(person_object, "alias")) {
+		value = json_object_get_string_member(person_object, "alias");
+		if(!purple_strempty(value)) {
+			purple_person_set_alias(person, value);
+		}
+	}
+
+	/* Create the link between the person and the contact info. */
+	if(new_person) {
+		purple_person_add_contact_info(person, info);
+		purple_contact_info_set_person(info, person);
+
+		g_clear_object(&person);
+	}
+}
+
+static void
+purple_demo_contacts_load_contact_presence(JsonObject *presence_object,
+                                           PurpleContactInfo *info)
+{
+	PurplePresence *presence = NULL;
+	const gchar *value = NULL;
+
+	presence = purple_contact_info_get_presence(info);
+
+	/* Emoji */
+	if(json_object_has_member(presence_object, "emoji")) {
+		value = json_object_get_string_member(presence_object, "emoji");
+		if(!purple_strempty(value)) {
+			purple_presence_set_emoji(presence, value);
+		}
+	}
+
+	/* Idle Time */
+	if(json_object_has_member(presence_object, "idle")) {
+		GDateTime *now = NULL;
+		GDateTime *idle_since = NULL;
+		gint64 ivalue = 0;
+
+		ivalue = json_object_get_int_member(presence_object, "idle");
+
+		now = g_date_time_new_now_local();
+		idle_since = g_date_time_add_minutes(now, -1 * ivalue);
+
+		purple_presence_set_idle(presence, TRUE, idle_since);
+
+		g_date_time_unref(idle_since);
+		g_date_time_unref(now);
+	}
+
+	/* Message */
+	if(json_object_has_member(presence_object, "message")) {
+		value = json_object_get_string_member(presence_object, "message");
+		if(!purple_strempty(value)) {
+			purple_presence_set_message(presence, value);
+		}
+	}
+
+	/* Mobile */
+	if(json_object_has_member(presence_object, "mobile")) {
+		gboolean bvalue = FALSE;
+		bvalue = json_object_get_boolean_member(presence_object, "mobile");
+		purple_presence_set_mobile(presence, bvalue);
+	}
+
+	/* Primitive */
+	if(json_object_has_member(presence_object, "primitive")) {
+		PurplePresencePrimitive primitive = PURPLE_PRESENCE_PRIMITIVE_OFFLINE;
+
+		value = json_object_get_string_member(presence_object, "primitive");
+		if(!purple_strempty(value)) {
+			GEnumClass *enum_class = NULL;
+			GEnumValue *enum_value = NULL;
+
+			enum_class = g_type_class_ref(PURPLE_TYPE_PRESENCE_PRIMITIVE);
+			enum_value = g_enum_get_value_by_nick(enum_class, value);
+
+			if(enum_value != NULL) {
+				primitive = enum_value->value;
+			}
+
+			g_type_class_unref(enum_class);
+		}
+
+		purple_presence_set_primitive(presence, primitive);
+	}
+}
+
+static void
+purple_demo_contacts_load_contact(PurpleContactManager *manager,
+                                  PurpleAccount *account,
+                                  JsonObject *contact_object)
+{
+	PurpleContact *contact = NULL;
+	PurpleContactInfo *info = NULL;
+	gboolean new_contact = FALSE;
+	const char *id = NULL;
+	const char *value = NULL;
+
+	/* If we have an id, grab so we can create the contact with it. */
+	if(json_object_has_member(contact_object, "id")) {
+		id = json_object_get_string_member(contact_object, "id");
+	}
+
+	/* Look for an existing contact before creating a new one. This stops us
+	 * from getting multiples when we trigger connection errors.
+	 */
+	if(!purple_strempty(id)) {
+		contact = purple_contact_manager_find_with_id(manager, account, id);
+	}
+
+	/* If we didn't find an existing contact, create it now with the provided
+	 * id.
+	 */
+	if(!PURPLE_IS_CONTACT(contact)) {
+		contact = purple_contact_new(account, id);
+		new_contact = TRUE;
+	}
+
+	info = PURPLE_CONTACT_INFO(contact);
+
+	/* Alias */
+	if(json_object_has_member(contact_object, "alias")) {
+		value = json_object_get_string_member(contact_object, "alias");
+		if(!purple_strempty(value)) {
+			purple_contact_info_set_alias(info, value);
+		}
+	}
+
+	/* Color */
+	if(json_object_has_member(contact_object, "color")) {
+		value = json_object_get_string_member(contact_object, "color");
+		if(!purple_strempty(value)) {
+			purple_contact_info_set_color(info, value);
+		}
+	}
+
+	/* Display Name */
+	if(json_object_has_member(contact_object, "display_name")) {
+		value = json_object_get_string_member(contact_object, "display_name");
+		if(!purple_strempty(value)) {
+			purple_contact_info_set_display_name(info, value);
+		}
+	}
+
+	/* Username */
+	if(json_object_has_member(contact_object, "username")) {
+		value = json_object_get_string_member(contact_object, "username");
+		if(!purple_strempty(value)) {
+			purple_contact_info_set_username(info, value);
+
+			purple_demo_contacts_load_contact_icon(info, value);
+		}
+	}
+
+	/* Load the profile if it exists. */
+	if(json_object_has_member(contact_object, "profile")) {
+		value = json_object_get_string_member(contact_object, "profile");
+		if(!purple_strempty(value)) {
+			g_object_set_data_full(G_OBJECT(info), "demo-profile",
+			                       g_strdup(value), g_free);
+		}
+	}
+
+	/* Load the tags. */
+	if(json_object_has_member(contact_object, "tags")) {
+		PurpleTags *tags = purple_contact_info_get_tags(info);
+		JsonArray *array = NULL;
+		GList *elements = NULL;
+
+		array = json_object_get_array_member(contact_object, "tags");
+		elements = json_array_get_elements(array);
+		while(elements != NULL) {
+			JsonNode *tag_node = elements->data;
+			const char *tag = json_node_get_string(tag_node);
+
+			purple_tags_add(tags, tag);
+
+			elements = g_list_delete_link(elements, elements);
+		}
+	}
+
+	/* Load the person. */
+	if(json_object_has_member(contact_object, "person")) {
+		JsonObject *person_object = NULL;
+
+		person_object = json_object_get_object_member(contact_object,
+		                                              "person");
+
+		purple_demo_contacts_load_contact_person(person_object, info);
+	}
+
+	/* Load the presence. */
+	if(json_object_has_member(contact_object, "presence")) {
+		JsonObject *presence_object = NULL;
+
+		presence_object = json_object_get_object_member(contact_object,
+		                                                "presence");
+
+		purple_demo_contacts_load_contact_presence(presence_object, info);
+	}
+
+	/* Finally add the contact to the contact manager if it's new. */
+	if(new_contact) {
+		purple_contact_manager_add(manager, contact);
+	}
+
+	g_clear_object(&contact);
+}
+
+/******************************************************************************
+ * Local Exports
+ *****************************************************************************/
+void
+purple_demo_contacts_load(PurpleAccount *account) {
+	PurpleContactManager *manager = NULL;
+	GError *error = NULL;
+	GInputStream *istream = NULL;
+	GList *contacts = NULL;
+	JsonArray *contacts_array = NULL;
+	JsonNode *root_node = NULL;
+	JsonParser *parser = NULL;
+
+	/* get a stream to the contacts.json resource */
+	istream = g_resource_open_stream(purple_demo_get_resource(),
+	                                 "/im/pidgin/purple/demo/contacts.json",
+	                                 G_RESOURCE_LOOKUP_FLAGS_NONE, NULL);
+
+	/* create our parser */
+	parser = json_parser_new();
+
+	if(!json_parser_load_from_stream(parser, istream, NULL, &error)) {
+		g_critical("%s", error->message);
+		g_clear_error(&error);
+		return;
+	}
+
+	root_node = json_parser_get_root(parser);
+
+	manager = purple_contact_manager_get_default();
+
+	/* Load the contacts! */
+	contacts_array = json_node_get_array(root_node);
+	contacts = json_array_get_elements(contacts_array);
+	while(contacts != NULL) {
+		JsonNode *contact_node = NULL;
+		JsonObject *contact_object = NULL;
+
+		contact_node = contacts->data;
+		contact_object = json_node_get_object(contact_node);
+
+		purple_demo_contacts_load_contact(manager, account, contact_object);
+
+		contacts = g_list_delete_link(contacts, contacts);
+	}
+
+	/* Clean up everything else... */
+	g_clear_object(&parser);
+
+	g_input_stream_close(istream, NULL, NULL);
+	g_object_unref(istream);
+}

mercurial