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);
+}