diff -r 000000000000 -r cc7c1f9d20f7 satoriapi.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/satoriapi.c Fri Aug 08 09:46:55 2025 +0800 @@ -0,0 +1,151 @@ +/* + * Purple Satori Plugin - Satori Protocol Plugin for Purple3 + * Copyright (C) 2025 Gong Zhile + * + * 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 . + */ + +#include +#include +#include +#include +#include +#include + + +#include "purplesatoriconnection.h" +#include "satorimessage.h" +#include "satoriapi.h" + +static void +satori_on_buddy_contacts_resp(SoupSession *session, + GAsyncResult *res, + PurpleSatoriConnection *con) +{ + GError *error = NULL; + GBytes *resp = soup_session_send_and_read_finish(session, res, &error); + + if (error) { + purple_debug_error("satori", + "refresh_buddy_contacts failed: %s", + error->message); + if (resp) + g_bytes_unref(resp); + g_error_free(error); + return; + } + + gsize sz; + const gchar *ptr = g_bytes_get_data(resp, &sz), *next = NULL; + + JsonParser *parser = json_parser_new(); + if (!json_parser_load_from_data(parser, ptr, sz, NULL)) { + purple_debug_warning("satori", "bad json received from ws"); + goto finish; + } + + JsonObject *root = json_node_get_object(json_parser_get_root(parser)); + JsonArray *data = json_object_get_array_member(root, "data"); + next = json_object_get_string_member_with_default( + root, "next", NULL); + + if (!data) goto finish; + + PurpleAccount *acc = \ + purple_connection_get_account(PURPLE_CONNECTION(con)); + PurpleContactManager *manager = \ + purple_contact_manager_get_default(); + + for (guint i = 0; i < json_array_get_length(data); i++) { + JsonObject *user_obj = json_array_get_object_element(data, i); + + SatoriUser user = { 0 }; + satori_user_from_json(user_obj, &user); + + PurpleContact *contact = NULL; + PurpleContactInfo *info = NULL; + PurplePresence *presence = NULL; + PurplePerson *person = NULL; + + gboolean new_contact = FALSE, new_person = FALSE; + + contact = purple_contact_manager_find_with_id(manager, acc, user.id); + if (!PURPLE_IS_CONTACT(contact)) { + contact = purple_contact_new(acc, user.id); + new_contact = TRUE; + } + + /* Initialize PurpleContactInfo */ + info = PURPLE_CONTACT_INFO(contact); + purple_contact_info_set_username(info, user.id); + purple_contact_info_set_display_name(info, user.nick ? + user.nick : user.name); + + /* Initialize PurplePerson */ + person = purple_contact_info_get_person(info); + if (!PURPLE_IS_PERSON(person)) { + person = g_object_new(PURPLE_TYPE_PERSON, + "id", user.id, NULL); + new_person = TRUE; + } + + if (new_person) { + purple_person_add_contact_info(person, info); + purple_contact_info_set_person(info, person); + g_clear_object(&person); + } + + /* Initialize PurplePresence */ + presence = purple_contact_info_get_presence(info); + purple_presence_set_primitive(presence, + PURPLE_PRESENCE_PRIMITIVE_AVAILABLE); + + if (new_contact) { + purple_contact_manager_add(manager, contact); + g_clear_object(&contact); + } + } + +finish: + if (next) + satori_refresh_buddy_contacts(con, next); + + g_bytes_unref(resp); + g_object_unref(parser); +} + +void +satori_refresh_buddy_contacts(PurpleSatoriConnection *con, const gchar *next) +{ + GBytes *data = NULL; + + { + JB_BEGIN_OBJ(b); + if (next) + JBA(b, "next", next); + JB_END_OBJ(data, b); + } + + SoupMessage *msg = satori_message_new( + "POST", SATORI_ENDPOINT("/v1/friend.list")); + soup_message_set_request_body_from_bytes(msg, "application/json", data); + + purple_satori_connection_send_and_read_async( + con, msg, 0, NULL, + (GAsyncReadyCallback) satori_on_buddy_contacts_resp, + PURPLE_SATORI_CONNECTION(con)); + + g_object_unref(msg); + g_bytes_unref(data); +}