Thu, 07 Aug 2025 21:34:33 -0500
Replace Purple.Avatar with Purple.Image
Purple.Avatar was unnecessary and this just moves everything to Purple.Image
which should work just fine.
Testing Done:
Loaded a demo account and verified that the avatars were shown in the contact list properly. Also called in the turtles.
Reviewed at https://reviews.imfreedom.org/r/4084/
/* * 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) { PurpleImage *avatar = NULL; GError *error = NULL; char *path = NULL; path = g_strdup_printf("/im/pidgin/libpurple/protocols/demo/buddy_icons/%s.png", name); avatar = purple_image_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_IMAGE(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_time(presence, 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/libpurple/protocols/demo/contacts.json", G_RESOURCE_LOOKUP_FLAGS_NONE, &error); if(!G_IS_INPUT_STREAM(istream)) { g_critical("%s", error->message); g_clear_error(&error); return; } /* 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); }